聊聊xxl-job二次开发 以及 IT糟糕的大环境

·  阅读 13313
聊聊xxl-job二次开发 以及 IT糟糕的大环境

“我报名参加金石计划1期挑战——瓜分10万奖池,这是我的第n篇文章,点击查看活动详情

闲聊


1、最近身边蛮多朋友被裁员,让我深切感受到这个糟糕的大环境,而且不是说个人能力不行🙅,先大环境不咋地,然后再到很多公司业务不咋地,然后按业务线来搞,所以那些被裁的也不要太难过。包括最近我们bg也有大动作

可以说在大环境下,危机四伏~

2、当然博主也是有些人脉,前几天有个大佬跟我打探前同事的情况,因为投了他们公司,不得不说圈子蛮小的,哈哈

image.png

3、平时周末感觉没什么事干,打球成了为数不多的兴趣,庆幸还是有点肌肉,哈哈

image.png

xxl-job 二次开发


为啥会谈到这个话题呢?

我记得很久之前,技术群有个oppo的大佬,广告营销组的,看业务组就知道是核心业务组,听说他们也对xxl-job进行改造,我当时就很好奇,这个框架不是很便捷吗,难道有什么不足?

那么今天我们就来聊聊xxl-job框架的不足

xxl-job介绍


这是大众点评许雪里开源的一个轻量级分布式任务调度框架,有个任务界面,将任务执行handle注册到调度中心,然后新建任务,里面会指定执行器名称,corn,失败重试次数,报警邮箱,执行相关参数,任务名称,我们可以看到比spring 自带定时器强大很多,然后也自带了全局任务执行结果的展示图。

image.png

image.png

image.png

不足的地方


  1. 当大量任务并发的时候,任务会丢失
  2. 当任务的那台服务器宕机之后,任务也会被中断,任务丢失会导致部分数据丢失
  3. kill任务的时候,有些数据是无法回滚的,会给修复数据带来麻烦

并发大导致任务丢失

这个需要我们进去源码里头看个究竟

image.png

我们从xxl-job任务执行curl找到执行的方法,新增促发,首先它会判断当前任务以往执行的情况,如果是比较快的,就丢到fast线程池,然后你一直执行high慢,那么把你丢到slow线程池。这样好处是避免那些执行时间很慢的任务阻塞了其他任务。

image.png

到这里其实平平无奇,就是搂出任务信息,任务组的信息(有多少个执行器注册上去),是否执行分片任务,这个是比较好的设计,就是当我们任务比较多的时候,可以通过集群来提高整个系统的处理速度。

image.png

到这里是执行的过程,类似http,拿到执行参数,点一下,嗖~返回请求结果,然后记录到日志里头

image.png

那么关键我们看下线程池

private ThreadPoolExecutor fastTriggerPool = null;\
private ThreadPoolExecutor slowTriggerPool = null;\
\
public void start(){\
    fastTriggerPool = new ThreadPoolExecutor(\
            10,\
            XxlJobAdminConfig.*getAdminConfig*().getTriggerPoolFastMax(),\
            60L,\
            TimeUnit.*SECONDS*,\
            new LinkedBlockingQueue<Runnable>(1000),\
            new ThreadFactory() {\
                @Override\
                public Thread newThread(Runnable r) {\
                    return new Thread(r, "xxl-job, admin JobTriggerPoolHelper-fastTriggerPool-" + r.hashCode());\
                }\
            });\
\
    slowTriggerPool = new ThreadPoolExecutor(\
            10,\
            XxlJobAdminConfig.*getAdminConfig*().getTriggerPoolSlowMax(),\
            60L,\
            TimeUnit.*SECONDS*,\
            new LinkedBlockingQueue<Runnable>(2000),\
            new ThreadFactory() {\
                @Override\
                public Thread newThread(Runnable r) {\
                    return new Thread(r, "xxl-job, admin JobTriggerPoolHelper-slowTriggerPool-" + r.hashCode());\
                }\
            });\
}
复制代码

我们可以看到核心线程数10个,满格是200个线程,然后缓冲区快的是1000,慢的线程池是2000

了解过线程池的小伙伴就知道,当我们超过max线程池+缓存区的数量会执行拒绝策略,采用默认的也就是丢弃策略,这就回答了为啥超过上千并发任务的时候就会导致任务丢失。

那么我来提个问题:上千任务并发正常吗?我认为一般小公司是无法达到这样的qps的,如果是大公司,然后大家的调度中心又是同一个,那么就会出现这种情况,比如说200个研发,每人写6个晚上9点执行的任务,好了炸了~

解决方案

我们可以通过之前美团介绍的动态更新线程池的方式,调大整个线程池的缓冲区数量,其次可以重写拒绝策略,当超过最大缓存数量的时候,先往数据库塞,然后当有空间的时候慢慢的读出然后删除待执行的记录。

服务宕机导致任务丢失

我来介绍下这种情况,就是每5分钟去拉增量数据的场景,如果中途有段任务没了,那么你的数据也会丢失,xxl-job的做法是重试,我们通过领域的思想来看,确实任务丢失是属于调度中心的问题,包括网络延迟等等问题,但是重试是无法彻底解决这个问题

解决方案

就是在我们业务端去缓存这个拉取的时间,比如说上次拉取是什么时候,如果中间有段丢失了,那我们下次任务就从上次丢失的地方开始拉数据,这样就补齐了。

这个要求开发同学有一定的定时任务处理经验,包括参数也应该设计为可配置化,如果出现什么意外,可以进行暗箱操作,比如说昨天数据没有同步到,那我们改下定时任务执行参数执行即可

image.png

kill任务导致部分数据问题

其实嘛,这个问题不应该发生的,为什么呢?

你的代码有问题,你把锅丢给任务调度中心,还要人家去优化,这是人才。kill任务的情况,意味着任务是有问题的,那么我们需要打印剔除掉的相关数据(无法回滚),比如说mq、redis,然后人工根据日志进行手动回滚

然后修复任务的逻辑,发版上线,这不就完事了吗,鹅鹅鹅🦢

image.png

好吧,我没啥要讲的,看完有帮助的话记得点赞关注~宝子们

分类:
后端
标签:
收藏成功!
已添加到「」, 点击更改