问题复现:
运维部分反馈数据库cpu占用和并发量非常高,看监控平台分析,cpu和并发规律是每隔20秒钟就升到极高,
分析:
初步判断是由于活动模块里面的优惠券模块里面的一个每隔20秒钟的定时任务查库造成的,每隔20秒钟这个定时任务会查库并将数据存到本地内存缓存,大促期间服务器节点在20台左右,这个定时任务用的是@schedule 单机的定时任务,相当于每隔20秒钟,20台机器同时查询。
解决方案:
1.将原来的@schedule 单机的定时任务改为ElasticJob分布式定时任务,这样只有1台机器查库,那怎么保证其他19台节点的内存缓存也能更新到数据呢?在定时任务内部,将数据查询先放到redis里面,然后发送一个广播消息(redis实现/mq实现),其余19个节点来消费,读取redis里面的数据,更新到本地缓存
2.注意启动的时候,加一个init方法,保证定时任务启动的20秒钟没有数据空白期
@Slf4j
@ElasticJob(cron = "0/10 * * * * ?", name = "", description = "优惠券商品同步缓存", eventTraceEnable = false)
public class SyncCouponCommodityCacheTask implements SimpleJob {
@Autowired
private CommodityCouponsCacheService cacheService;
@Autowired
private MessageService messageService;
@Override
public void execute(ShardingContext shardingContext) {
log.info("SyncCouponCommodityCacheTask 开始");
//同步redis缓存
boolean result = cacheService.loadRedisCache(false);
if (!result) {
log.error("SyncCouponCommodityCacheTask 同步redis缓存失败");
return;
}
//发送广播消息同步内存缓存
messageService.publish(ModuleConsts.CHD_P_ACTIVITY_CACHE_REFRESH_CHANNEL,
PlatformMessage.of(ActivityCacheRefreshMessageConsumer.MessageType.优惠券.getType()));
log.info("SyncCouponCommodityCacheTask 结束");
}
}