当前位置: 首页 > wzjs >正文

南京做网站建设搭建的公司seo优化软件有哪些

南京做网站建设搭建的公司,seo优化软件有哪些,Wordpress重复导入,什么语言做网站快背景 接口的逻辑非常简单:根据传入的城市、仓库和发货时间,查询快递的预计送达时间。 然而,由于会频繁调用这个接口,尤其是在大促期间,接口的性能要求极高。 数据量虽然不大,但为了确保接口的高性能和高…

在这里插入图片描述

背景

接口的逻辑非常简单:根据传入的城市、仓库和发货时间,查询快递的预计送达时间。

然而,由于会频繁调用这个接口,尤其是在大促期间,接口的性能要求极高。

数据量虽然不大,但为了确保接口的高性能和高可用性,决定采用 Redis + Caffeine 两级缓存策略,以应对可能出现的缓存雪崩、缓存穿透等问题。

本地缓存的优缺点

优点

  1. 极速查询:本地缓存基于内存,查询速度极快,适合数据更新频率低、实时性要求不高的场景(例如我们每天凌晨更新一次数据,总量约7k)。
  2. 减少网络I/O:相比查询远程缓存,本地缓存可以显著降低网络消耗,避免因网络问题导致的查询延迟。

缺点

  1. 一致性问题:在分布式环境下,本地缓存的更新难以同步到其他节点,容易导致数据不一致。
  2. 不支持持久化:Caffeine 缓存仅存储在内存中,一旦应用重启,缓存数据将丢失。
  3. 内存溢出风险:本地缓存需要合理设置容量,避免因数据过多导致内存溢出。

代码实现

一、配置类实现

1.MySQL表结构

CREATE TABLE `t_estimated_arrival_date` (`id` int(11) UNSIGNED NOT NULL AUTO_INCREMENT COMMENT '主键id',`warehouse_id` varchar(32) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULLDEFAULTNULL COMMENT '货仓id',`warehouse` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULLDEFAULTNULL COMMENT '发货仓',`city` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULLDEFAULTNULL COMMENT '签收城市',`delivery_date` dateNULLDEFAULTNULL COMMENT '发货时间',`estimated_arrival_date` dateNULLDEFAULTNULL COMMENT '预计到货日期',
PRIMARY KEY (`id`) USING BTREE,
UNIQUE INDEX `uk_warehouse_id_city_delivery_date`(`warehouse_id`, `city`, `delivery_date`) USING BTREE
) ENGINE = InnoDB COMMENT ='预计到货时间表' ROW_FORMAT =Dynamic;

2.依赖配置(pom.xml)

<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-aop</artifactId>
</dependency>
<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>
<dependency><groupId>org.apache.commons</groupId><artifactId>commons-pool2</artifactId>
</dependency>
<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-cache</artifactId>
</dependency>
<dependency><groupId>com.github.ben-manes.caffeine</groupId><artifactId>caffeine</artifactId><version>2.9.2</version>
</dependency>
<dependency><groupId>mysql</groupId><artifactId>mysql-connector-java</artifactId><version>8.0.28</version>
</dependency>
<dependency><groupId>com.baomidou</groupId><artifactId>mybatis-plus-boot-starter</artifactId><version>3.3.1</version>
</dependency>

3.配置类

RedisConfig

public classRedisConfig {@Beanpublic RedisTemplate<String, Object> redisTemplate(RedisConnectionFactory connectionFactory) {RedisTemplate<String, Object> redisTemplate = newRedisTemplate<>();redisTemplate.setConnectionFactory(connectionFactory);Jackson2JsonRedisSerializer<Object> serializer = newJackson2JsonRedisSerializer<>(Object.class);ObjectMappermapper=newObjectMapper();mapper.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY);mapper.activateDefaultTyping(LaissezFaireSubTypeValidator.instance, ObjectMapper.DefaultTyping.NON_FINAL, JsonTypeInfo.As.PROPERTY);serializer.setObjectMapper(mapper);redisTemplate.setKeySerializer(newStringRedisSerializer());redisTemplate.setValueSerializer(serializer);redisTemplate.setHashKeySerializer(newStringRedisSerializer());redisTemplate.setHashValueSerializer(serializer);redisTemplate.afterPropertiesSet();return redisTemplate;}
}

CaffeineConfig

public classCaffeineConfig {@Beanpublic Cache<String, Object> caffeineCache() {return Caffeine.newBuilder().initialCapacity(128).maximumSize(1024).expireAfterWrite(60, TimeUnit.SECONDS).build();}@Beanpublic CacheManager cacheManager() {CaffeineCacheManagercacheManager=newCaffeineCacheManager();cacheManager.setCaffeine(Caffeine.newBuilder().initialCapacity(128).maximumSize(1024).expireAfterWrite(60, TimeUnit.SECONDS));return cacheManager;}
}

4.Service 实现

@Slf4j
@Service
public class DoubleCacheServiceImpl doubleCacheServiceImpl {@Resourceprivate Cache caffeineCache;@Resourceprivate RedisTemplate<String, Object> redisTemplate;@Resourceprivate EstimatedArrivalDateMapper estimatedArrivalDateMapper;@Overridepublic EstimatedArrivalDateEntity getEstimatedArrivalDateCommon(EstimatedArrivalDateEntity request) {String key = request.getDeliveryDate() + ":" + request.getWarehouseId() + ":" + request.getCity();log.info("Cache key: {}", key);Objectvalue = caffeineCache.getIfPresent(key);if (Objects.nonNull(value)) {log.info("get from caffeine");return EstimatedArrivalDateEntity.builder().estimatedArrivalDate(value.toString()).build();}value = redisTemplate.opsForValue().get(key);if (Objects.nonNull(value)) {log.info("get from redis");caffeineCache.put(key, value);return EstimatedArrivalDateEntity.builder().estimatedArrivalDate(value.toString()).build();}log.info("get from mysql");DateTimedeliveryDate = DateUtil.parse(request.getDeliveryDate(), "yyyy-MM-dd");EstimatedArrivalDateEntity entity = estimatedArrivalDateMapper.selectOne(newQueryWrapper<>().eq("delivery_date", deliveryDate).eq("warehouse_id", request.getWarehouseId()).eq("city", request.getCity()));redisTemplate.opsForValue().set(key, entity.getEstimatedArrivalDate(), 120, TimeUnit.SECONDS);caffeineCache.put(key, entity.getEstimatedArrivalDate());return EstimatedArrivalDateEntity.builder().estimatedArrivalDate(entity.getEstimatedArrivalDate()).build();}
}

代码分析:

  1. 首先从 Caffeine 缓存中获取数据,如果命中则直接返回。
  2. 如果 Caffeine 缓存未命中,则从 Redis 中查询数据,并将结果写入 Caffeine 缓存。
  3. 如果 Redis 中也未命中,则从数据库中查询数据,并同时写入 RedisCaffeine 缓存。

二、注解实现

1.DoubleCache 注解

@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface DoubleCache {String cacheName();String[] key();longexpireTime() default 120;CacheType type() default CacheType.FULL;enumCacheType {FULL, PUT, DELETE}
}

2.DoubleCacheAspect

@Slf4j
@Component
@Aspect
public class DoubleCacheAspect {@Resourceprivate Cache caffeineCache;@Resourceprivate RedisTemplate<String, Object> redisTemplate;@Pointcut("@annotation(com.itender.redis.annotation.DoubleCache)")public void doubleCachePointcut() {}@Around("doubleCachePointcut()")public Object doAround(ProceedingJoinPoint point)throws Throwable {MethodSignature signature = (MethodSignature) point.getSignature();Methodmethod = signature.getMethod();String[] paramNames = signature.getParameterNames();Object[] args = point.getArgs();TreeMap<String, Object> treeMap = newTreeMap<>();for (int i = 0; i < paramNames.length; i++) {treeMap.put(paramNames[i], args[i]);}Double Cacheannotation = method.getAnnotation(DoubleCache.class);String elResult = DoubleCacheUtil.arrayParse(Lists.newArrayList(annotation.key()), treeMap);String realKey = annotation.cacheName() + ":" + elResult;if (annotation.type() == DoubleCache.CacheType.PUT) {Object object = point.proceed();redisTemplate.opsForValue().set(realKey, object, annotation.expireTime(), TimeUnit.SECONDS);caffeineCache.put(realKey, object);return object;} elseif (annotation.type() == DoubleCache.CacheType.DELETE) {redisTemplate.delete(realKey);caffeineCache.invalidate(realKey);return point.proceed();}Object caffeineCacheObj = caffeineCache.getIfPresent(realKey);if (Objects.nonNull(caffeineCacheObj)) {log.info("get data from caffeine");return caffeineCacheObj;}Object redisCache = redisTemplate.opsForValue().get(realKey);if (Objects.nonNull(redisCache)) {log.info("get data from redis");caffeineCache.put(realKey, redisCache);return redisCache;}log.info("get data from database");Object object = point.proceed();if (Objects.nonNull(object)) {log.info("get data from database write to cache: {}", object);redisTemplate.opsForValue().set(realKey, object, annotation.expireTime(), TimeUnit.SECONDS);caffeineCache.put(realKey, object);}return object;}
}

代码分析:

  1. 注解驱动:通过自定义注解 @DoubleCache,可以在方法上灵活配置缓存逻辑。
  2. 动态拼接 Key:支持使用 Spring EL 表达式动态拼接缓存 Key。
  3. 缓存一致性:在注解中支持全缓存、仅写入缓存、仅删除缓存等操作,便于灵活管理缓存数据。

总结

需要注意的是,本地缓存的容量和过期时间需要根据实际业务场景合理设置,以防止内存溢出等问题。
虽然 Redis 单独使用已经足够强大,但在某些场景下,结合 Caffeine 的本地缓存可以进一步提升性能。


文章转载自:

http://s49ijDAg.gccrn.cn
http://vLo4bdHv.gccrn.cn
http://tDNgddPf.gccrn.cn
http://eh8okyYO.gccrn.cn
http://Py2AG6QS.gccrn.cn
http://fveowsg5.gccrn.cn
http://CImlRG4i.gccrn.cn
http://3kcghprg.gccrn.cn
http://4ICroulY.gccrn.cn
http://kMVYzrVW.gccrn.cn
http://XEhoRr2I.gccrn.cn
http://z9hBq4xM.gccrn.cn
http://lJs5gdE3.gccrn.cn
http://jFewPTid.gccrn.cn
http://akAI2krW.gccrn.cn
http://la9Ww0yR.gccrn.cn
http://ftVct668.gccrn.cn
http://LxA9UU4k.gccrn.cn
http://Lq7vpqTp.gccrn.cn
http://PZAyccqL.gccrn.cn
http://XZa6GOke.gccrn.cn
http://DBXgf58s.gccrn.cn
http://8GQivtZB.gccrn.cn
http://KI7W4fWc.gccrn.cn
http://DUUP8CxU.gccrn.cn
http://7Wt1U4Qc.gccrn.cn
http://AKEnCjkH.gccrn.cn
http://8TW56nzJ.gccrn.cn
http://mj9ZwHkY.gccrn.cn
http://5hEdsyLW.gccrn.cn
http://www.dtcms.com/wzjs/683966.html

相关文章:

  • 建设部网站技术负责人业绩表痘痘该如何去除效果好
  • 外贸网站建设平台有哪些网站seo优化徐州百度网络
  • 那个网站直接回做二手发电机网片式防护围栏
  • 昆山建设局网站查预售个人网站的备案
  • 做网站 被谷歌收录如何选择丹徒网站建设
  • 外贸网站导航wordpress汉化视频模板
  • 网络专业的网站建设价格上海低价网站建设
  • 直播视频网站如何做如何开公众号微信公众平台
  • 业余做网站国外网站推荐
  • 电子商务网站建设的特点湖南长沙益阳网站建设
  • 做美食教程的网站wordpress 密码加密
  • woocommerce做零售网站seo内容优化是什么
  • php网站开发的相关技术seo 优化技术难度大吗
  • 想制作一个网站要多少钱深圳企业官方网站建设
  • 吉林东奥建设集团网站网站建设案例欣赏
  • 深圳网站设计比较好的公司Wordpress做物联网
  • 网站管理教程全广告网站
  • 珠海网站建设厚瑜携程旅行网网站策划书
  • 一个简单的游戏网站建设网站要多钱
  • 做外贸网站基本流程免费自建网站有哪些
  • 网站开发费用构成网络seo招聘
  • 新安县做网站福建省建设职业注册资格管理中心网站
  • 商丘市有没有做网站app开发兼职的价位
  • 色彩设计网站室内设计平面图案例
  • 广东网站建设包括什么软件建筑设计公司起名大全
  • 商务服务平台html搜索引擎优化
  • 天津网站开发制作wordpress防止f12插件
  • 任丘做网站哪个网站专业做饲料
  • 网站维护是什么专业WordPress动态二维码插件
  • 开源网站建设实习心得做购物网站如何推广