xxl-job的demo使用及源码解读

demo搭建:

1、下载xxl-job调度中心代码:

       可从这两个地址下载:

          https://github.com/xuxueli/xxl-job
          https://gitee.com/xuxueli0323/xxl-job

2、执行脚本:

     下载后解压用idea打开,目录 doc/db 下面有个 tables_xxl_job.sql 脚本,是xxl-job调度中心用到的一些表,拖到数据库中执行即可

3、修改调度中的的配置文件:

           application.property,修改数据库链接即可:

4、启动调度中心

          启动xxl-job-admin,默认访问地址是:http://localhost:8080/xxl-job-admin,admin/123456

5、搭建执行器:

       我新建的spring boot 项目,需要添加xxl-job的配置如下,其中xxl.job.accessToken 的值要和调度中心一样 

  引入 xxl-job 的jar包:

 添加执行配置器:

 

        添加执行器代码,使用 @XxlJob 注解

6、启动执行器并在调度中心中配置执行器:

      启动执行器,此时执行器在 xxl-job 中还没有配置,所以执行器不会执行

      打开调度中心控制台,配置任务:

             JobHandler 中填写 执行器方法 @XxlJob注解的值

             路由策略 中可以选择负载均衡策略(适用集群部署的执行器)

填写完后 保存,此时可以看到新建的任务,可以对任务进行启动\停止等操作:

7、计划任务的分片:

       如果定时任务需要处理的数据量比较大,一个服务器处理时间长,此时可以使用分片策略

      分片策略是给每个执行器节点都发起请求,执行器可以获取到总分片数和当前分片数,根据这两个参数进行任务的派分,如有1000条数据需要处理,用1000除以总分片数得到每台服务器处理的数量,然后根据当前分片数获取要处理的数据

      将路由策略改成分片广播:

执行器获得总分片数和当前分片:

执行器管理中可以看到一个任务有哪些执行器:执行器启动后向调度中心发送心跳,调度中心的执行器管理中就可以看到了;

xxl-job的源码解读:

   1、调度中心源码:

        从xxl-job-admin的XxlJobAdminConfig进入,从后置处理器(后置处理器是在bean创建后执行的方法)afterPropertiesSet的init()进入,源码逻辑如下:

/**
 * 创建两个线程池:fastTriggerPool,slowTriggerPool
 *    如果一分钟内一个任务有10次执行时间超过0.5秒,则使用 是slowTriggerPool
 *    这两个线程池都是用来调用执行器的,其中 fastTriggerPool的队列中 最大任务数量和最大线程数量 是slowTriggerPool 的两倍
 *    执行器的调用是异步调用,通过下面的线程池 callbackThreadPool 回调
 */
JobTriggerPoolHelper.toStart();

/**
 * 1、创建线程池 registryOrRemoveThreadPool,用于服务器注册、服务器移除
 *    以下每30秒执行一次(心跳时间间隔)
 * 2、移除掉 90 秒没有收到心跳的执行器,
 * 3、将90秒内收到心跳的执行器 地址更新到 xxl_job_group.address_list
 */
JobRegistryHelper.getInstance().start();

/**
 * 每10秒执行一次
 * 查询 xxl_job_log 中处理失败的日志,如果剩余重试次数大于0,则执行一次任务
 * 对执行失败的任务,进行告警(邮件通知),告警之后更新 xxl_job_log.alarm_status 告警状态
 */
JobFailMonitorHelper.getInstance().start();

/**
 * 1、创建 线程池 callbackThreadPool,用于执行器执行任务之后回调
 * 2、调度记录停留在 "运行中" 状态超过10min,且对应执行器心跳注册失败不在线,则将本地调度主动标记失败, 更新 xxl_job_log.handle_time、handle_code、handle_msg(每60秒执行一次)
 *    以下是回调源码,使用线程池 callbackThreadPool 执行
 */
JobCompleteHelper.getInstance().start();


/**
 * 每分钟执行一次
 * 将任务执行的总数、成功数、失败数 写入到 xxl_job_log_report
 * 根据配置的日志保留时间 删除 xxl_job_log
 */
JobLogReportHelper.getInstance().start();

/**
 * 以下步骤调用执行器,每秒执行一次(线程最后睡眠一秒)
 * 首先获得分布式锁:
 *   select * from xxl_job_lock where lock_name = 'schedule_lock' for update
 *   1、查询 xxl_job_info 任务信息: 下次实行时间(trigger_next_time<当前时间+5秒)、执行器 trigger_status 状态为 有效,也就是任务管理配置的 running 状态、限制查询 6000 条数据
 *      (1)、当前时间大于 下次执行时间加5秒,如果任务 调度过期策略是执行一次,则执行一次任务(写入xxl_job_log 失败剩余次数改为默认次数),刷新下一次执行时间
 *      (2)、当前时间减去 下一次执行时间小于5秒,则执行任务 并 执行任务后刷新下一次执行时间,刷新后当前时间距离下一次执行时间 小于 5秒,将任务id放在 ringData 中
 *      (3)、当前时间小于下次执行时间,将要执行数据放到 ringData 中并刷新 下次执行时间
 */
JobScheduleHelper.getInstance().start();

下图为调用执行器的代码:executorHandler 的值是执行器方法上面 @XxlJob 的值

      2、执行器源码解读:

          进入到XxlJobConfig中创建的bean(XxlJobSpringExecutor),进入方法afterSingletonsInstantiated(这个方法是所有的bean都创建完成后执行):           

          (1)、initJobHandlerMethodRepository  找到使用xxl-job注解的方法,将方法放入 jobHandlerRepository

          (2)、super.start() 方法逻辑,主要是最后一步比较复杂,使用netty了,从channel中获得调度中心的的请求放入triggerQueue中,然后使用一个线程从triggerQueue取出handler来执行业务方法,根据调度中心传过来的executorHandler 从 jobHandlerRepository 中获得执行的方法

       // 初始化日志目录
        XxlJobFileAppender.initLogPath(logPath);

        // 初始化AdminBiz(注册中心地址、access_token)
        initAdminBizList(adminAddresses, accessToken);


        /*
        * 清除日志文件,logRetentionDays 小于3 时不执行清除逻辑,每天执行一次
        */
        JobLogFileCleanThread.getInstance().start(logRetentionDays);

        // 执行器执行任务后回调调度中心,记录日志
        TriggerCallbackThread.getInstance().start();

        /**
        * 执行器注册或发送心跳,30秒一次,调用注册中心 api/registry
        * 这一步使用netty实现,指定线程池 bizThreadPool 来接收注册中心的调度请求,(EmbedHttpServerHandler.channelRead0.process)从jobHandlerRepository通过jobId获取handler,如果handler不为空则启动线程JobThread,然后将请求放入到 triggerQueue 中,并返回注册中心
        *   JobThread线程从triggerQueue获取handler,依次执行里面的任务,执行任务后将执行结果放入
callBackQueue队列中

        *   TriggerCallbackThread callBackQueue 中取出执行结果,回调调度中心(api/callback)
        */
        initEmbedServer(address, ip, port, appname, accessToken);

执行结果放入callBackQueue队列:

下面是下载的xxl-job调度中心代码及 执行器demo:

链接:https://pan.baidu.com/s/1iWCscUvWoVeHmRaj-6OpZg?pwd=44hp 
 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值