springBoot项目中,定时任务短时间内执行多次异常情况(已解决)

情况:

​ 我使用的是注解@Scheduled设置的定时任务,每五分钟执行一次,但是项目却有时候会同一时刻执行多次
在这里插入图片描述

还发出了黄色警告

2023-10-30T19:32:19.874+08:00 WARN 7960 — [l-1 housekeeper] com.zaxxer.hikari.pool.HikariPool : HikariPool-1 - Thread starvation or clock leap detected (housekeeper delta=1h7m20s50ms583µs900ns).

数据库中也同时插入多条数据

在这里插入图片描述

原因:

​ 在查询资料之后发现,上面的警告说的就是由Hikari连接池的线程饥饿或时钟跳跃引起的。这可能是因为连接池中的线程长时间处于繁忙状态,无法满足并发请求,或者系统时钟在某个时间点发生了跳跃。

​ 再经过思考以及对比之后,我发现这种情况是出现再项目运行过程中,忽然断网之后,再次连接网络时出现的

​ 再次经过思考之后,出现这种情况的原因应该是因为: 在断网之后,启动了第一个定时任务(启动了一个线程),在第一个任务中,向远程发起了请求,但是因为断网,一直得不到回应,任务一直无法结束,之后的任务依旧按时执行,但是同样无法结束,就这样一直堆积,在联网之后就一起爆发出来了

进一步探索:断网导致的任务堆积

在这里插入图片描述

​ 可以看出,是从18:24之后就断网了,在19:32恢复网络,之后就开始爆发式执行任务,在查询资料之后发现,这是断网导致的任务堆积

​ 同时堆积的任务个数*五分钟,刚好等于断网时间,进一步证明了这个

解决:

​ 思路很简单,只需要在执行定时任务之前,检查是否联网,未联网则直接结束定时任务,避免定时任务堆积

	@Async
    @Scheduled(fixedRateString = "3000", initialDelay = 0)
    public void executeSaveClimateData(){
        if(isNetworkConnected()){
            //定时任务逻辑
        } else {
            log.warn("网络连接异常");
        }
    }

    private boolean isNetworkConnected() {
        // 检测网络连接状态的逻辑
        try {
            // 尝试连接一个公共的DNS服务器(如谷歌)
            InetAddress.getByName("8.8.8.8").isReachable(1000);
            return true;
        } catch (IOException e) {
            return false;
        }
    }

为什么会出现断网导致任务堆积?

Spring Boot默认使用的调度框架是Spring Framework中的Task Scheduling(任务调度)功能。这个功能基于Java的ScheduledExecutorService实现,并提供了一些便捷的注解和配置来进行任务调度。

​ 在默认情况下,当任务由@Scheduled注解标记并配置了适当的定时表达式时,Spring会创建一个线程池来执行这些任务。如果任务无法按计划执行(例如因为断网),Spring不会对其进行特殊处理。

​ 这意味着,如果应用程序发生了网络中断,然后网络恢复,那么未执行的定时任务将被放置在队列中等待执行。当网络恢复后,任务将立即开始执行。如果有多个任务同时触发,它们可能会并发地执行,并在短时间内产生任务堆积

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值