关于spring定时钟异常停止的解决方案

背景:
功能简介: 项目中有一个功能: 定时钟(每5分钟)增量更新产品数据到es.
大致逻辑: 单表查询大量元数据添加到redis, 然后依据redis中的元数据更新产品数据到es.
配置定时钟方式: @Scheduled(cron = “${task.product.incr.cron}”)

现象:
定时钟执行几百次之后, 会异常停止, 再也不执行, 每次都用重启服务的方式解决.

研究出的一些点:
1. 本次定时钟只要未执行完毕, 下次定时钟就不会执行.

本人解决此问题的一些记录:
前期:
方式: 各种优化程序.
结果: 定时钟有效执行次数增加了, 但是还是会异常停止.

中期:
同前期

后期:
方式:
1.从大量日志中定位问题, 发现某次定时钟的异常停止没有报错, 是执行一个千次级的循环代码时小概率性程序卡死, 导致后面的定时钟不执行, 无法在代码上定位原因
2.偶然发现java.util.concurrent.Future可以利用, Future类作用: 可以给一个方法设置超时时间, if(超时) -> throw TimeoutException
3.所以代码变更为:

ExecutorService executorService = Executors.newSingleThreadExecutor();
// callable里有定时钟要执行的方法体
Future<String> future = executorService.submit(callable);
try {
	future.get(20, TimeUnit.MINUTES);
} catch (InterruptedException e) {
	log.info("本次产品同步异常(InterruptedException)");
} catch (ExecutionException e) {
	log.info("本次产品同步异常(ExecutionException)");
} catch (TimeoutException e) {
	log.info("本次产品同步异常(TimeoutException)");
} finally {
	isRuningProductSyncTask = false;
	incrTaskExcuteCount ++;
	log.info("本次产品同步完成, 耗时: {}秒", (System.currentTimeMillis() - startTime) / 1000);
}

其中callable记录了需要执行的方法(设置了20分钟超时):

Callable<String> callable = new Callable<String>() {
	
	@Override
	public String call() throws Exception {
		try {
			if(incrTaskExcuteCount % fullSyncNum == 0 && incrTaskExcuteCount != 0) {
				log.info("准备执行产品\"全量\"同步, incrTaskExcuteCount = {}", incrTaskExcuteCount);
				productFullSync();
			}else {
				log.info("准备执行产品\"增量\"同步, incrTaskExcuteCount = {}", incrTaskExcuteCount);
				productIncrSync();
			}
		} catch (Exception e) {
			e.printStackTrace();
			log.error(CLASS_LOG_PREFIX + e.getMessage());
		} 
		return "over";
	}
	
};

4.达到的效果: 即使定时钟程序小概率卡死, 也能在20分钟后跳出本次定时钟以便继续执行下次定时钟

结果:
比较理想,没有出现过定时钟异常停止的问题

总结:
并没有从根本上解决此问题(没有治本)(/捂脸), 换了一种方式解决此问题

关键字:
spring定时钟, 定时钟停止, 定时钟异常停止, java, @Scheduled

  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值