反思Spring Task定时任务没有等待Dubbo接口执行完成重复执行的问题

一、前情回顾

        Long long ago,我记得有一个严重的线上BUG,前一天晚上上线了一个消息系统的改变需求,在一个宁静的周末,公司运营要用消息系统给平台客户发送消息,周五半夜收到数据库报警,早晨发现所有消息系统定时任务都卡住,没有继续执行,到了十二点,一下子将所有短信发送出去,直到短信账户欠费,然后系统恢复正常,最后发现
一个用户重复发了十几条短信。

二、剧情分析

  • 1、研究消息系统改版需求业务逻辑,并无大发现。
  • 2、研究数据库告警,发现某一个慢SQL的问题引发了“蝴蝶效应”,大部分的SQL都是慢SQL,以至于无法定位慢SQL。
  • 3、再研究代码,发现消息系统设计是使用Spring Task条用Dubbo接口,一个定时任务时间进入业务方法,直接调用一个Dubbo接口,研究发现,task调起Dubbo接口后,并不等待Dubbo接口执行完成就直接结束当前task,五分钟后下一个task开始执行,此时,上一个task还没有执行完成,……以此叠加,引发多个task并发执行,慢SQL的问题越来越凸显,最后促使系统崩溃。。。

三、观后聆思

  • 1、写代码需要充分考虑健壮性
  • 2、Spring的bean默认是单例,如果存在公共变量需要考虑并发问题,如果需要控制并发,或许你需要使用Lock
  • 3、对于SQL,应尽量避免使用慢SQL写法,否则可能会引发系统雪崩