面试题——定时任务数据过大如何处理

题目:
分布式任务调度如果说10w条任务一分钟处理会出现什么,怎么解决

前言:
对前面不感兴趣可以直接看第四个解决方案

这个是笔者以前遇到过的面试题(因为笔者以前项目有用到Xxl-Job),最近刷群友发现被别的面试官问到相似的问题,故重拾一下此题探讨一下解决方案,我将分为不同的业务场景进行讨论,因为脱离了业务的技术是没有太多意义的

一、背景
目前来说 接触的Xxl-Job比较多 所以我后续的讨论都将基于Xxl-Job进行
不了解Xxl-Job可以移步分布式任务调度平台XXL-JOB

二、对时间要求高的原生的解决方案
面试题——定时任务数据过大如何处理_第1张图片如图所示 Xxl-Job自带分片广播的功能,利用分布式系统调度的特点进行多任务执行

    @XxlJob("shardingJobHandler")
    public void shardingJobHandler() throws Exception {

        // 分片参数
        int shardIndex = XxlJobHelper.getShardIndex();
        int shardTotal = XxlJobHelper.getShardTotal();

        XxlJobHelper.log("分片参数:当前分片序号 = {}, 总分片数 = {}", shardIndex, shardTotal);

        // 业务逻辑
        for (int i = 0; i < shardTotal; i++) {
            if (i == shardIndex) {
                XxlJobHelper.log("第 {} 片, 命中分片开始处理", i);
            } else {
                XxlJobHelper.log("第 {} 片, 忽略", i);
            }
        }

    }

风险点在于 —— xxlJob只负责了任务调度 时间相对来说仍旧是不可控的
举个例子 分片广播+串行 目前机器有五台 第一次任务进来,分片到五台上进行执行,然后第二次任务进来了,Xxl-Job因为只管理资源调度,且每台机器资源性能不完全一致,会有可能造成第一次任务的分片再1号机器上完成了,开始第二次任务 但是 第二台机器还在执行第一次的任务。
所以是业务代码需要保证幂等和健壮的

三、 时间不敏感的任务
时间不敏感任务可以半夜设置刷库时间,比如一些状态检查的同步,一天一次就可以的那种,就晚上两三点进行一次单机同步,让他慢慢去同步即可
 

    @XxlJob("demoJobHandler")
    public void demoJobHandler() throws Exception {
        XxlJobHelper.log("XXL-JOB, Hello World.");

        for (int i = 0; i < 5; i++) {
            XxlJobHelper.log("beat at:" + i);
            TimeUnit.SECONDS.sleep(2);
        }
        // default success
    }

四、业务定时任务
举个例子:我们经常会今天去定明天的早餐,正常的app或许是到明日九点才触发这个请求,才把这个业务推送给商家,这个时候就算是业务上的定时任务了,和上述的定时任务不太一样
显而易见的思路就是专门为这个业务造一张表,有订餐就可以写在这个业务表上,然后重复上面第二大点的步骤,执行器到点发推送即可

不过这边提出一个更为通用(个人认为很有意思的解决方案),利用Xxl-Job 和 RocketMQ共同抽象成一个公有的业务定时任务执行器
核心流程如下
面试题——定时任务数据过大如何处理_第2张图片

核心就是抽象层一个共有的执行器,这个执行器职责单一,只负责记录定时时间,到点发送MQ给业务进行消费

回归原来的问题,这个项目下,能解决定时任务执行量大的问题吗?
两个角度讨论,第一个:执行器数据量大,执行器上记载了很多任务,但是注意,因为执行器任务单一只负责给业务发MQ,所以其实处理能力是极强的,我个人认为这个地方影响不大,不行就用Xxl-Job进一步分片呗
第二个问题:业务收到大量的任务执行问题
多个Queue讲数据打散分发,这个本身就是天然的分布式的解决方案,不够?不够就再加队列!

和笔者的朋友又探讨了一下,朋友给了我一个非常实用的建议——区分任务优先度
下面我又将从两个角度去思考任务优先级的区分
首先是对于执行器项目——既然都是改造xxl-job,对于有需求的优先级任务 我们可以为他设计专表,表中只存储这一个业务数据
其次是对于MQ的使用去区分优先级,已知MQ是有TOPIC,我们开始的设计便是执行器项目往MQ上发消息,那么只需要按业务指定发送的TOPIC位置,优先级高的业务自己申请一个TOPIC,自己用更多资源消费这个专门的TOPIC,便可以实现天然的优先级分类了
 

你可能感兴趣的:(java,面试)