侧边栏壁纸
博主头像
憨憨大头个人博客博主等级

心存希冀,目有繁星

  • 累计撰写 110 篇文章
  • 累计创建 13 个标签
  • 累计收到 0 条评论

目 录CONTENT

文章目录

xxl-job(分布式任务调度平台)的介绍和原理

Administrator
2023-02-02 / 0 评论 / 0 点赞 / 10 阅读 / 5413 字

传统@Scheduled定时器缺点

根据业务需要,在方法上使用@Scheduled注解,cron属性配置定时规则

@Component
public class ScheduledTask {
    private final static Logger logger = LoggerFactory.getLogger(MethodHandles.lookup().lookupClass());
    @Scheduled(cron = "0/10 * * * * ?") //每10秒执行一次
    public void scheduledTaskByCorn() {
        logger.info("定时任务开始 ByCorn:" + new Date());
        scheduledTask();
        logger.info("定时任务结束 ByCorn:" + new Date());
    }
    private void scheduledTask() {
        try {
            Thread.sleep(5000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }
}

  • 不支持集群:集群情况下容易造成任务重复问题
  • 不支持失败重试:失败即结束,不支持重试
  • 不支持动态调整:修改任务参数时需要修改代码,并且要重启服务
  • 无报警机制:任务失败后没有提醒功能
  • 无统一管理:没有办法手动关闭或开启任务

初识xxl-job

XXL-JOB是一个开源的,具有丰富的任务管理功能以及高性能,高可用等特点的轻量级分布式任务调度平台,其核心设计目标是开发迅速、学习简单、轻量级、易扩展、开箱即用!!!
系统组成:

官方文档:https://www.xuxueli.com/xxl-job/
github地址:https://github.com/xuxueli/xxl-job
gitee地址:https://github.com/xuxueli/xxl-job

  1. 调度模块(调度中心): 负责管理调度信息,按照调度配置发出调度请求,自身不承担业务代码。调度系统与任务解耦,提高了系统可用性和稳定性,同时调度系统性能不再受限于任务模块; 支持可视化、简单且动态的管理调度信息,包括任务新建,更新,删除,任务报警等,所有上述操作都会实时生效,同时支持监控调度结果以及执行日志,支持执行器Failover
  2. 执行模块(执行器): 负责接收调度请求并执行任务逻辑。任务模块专注于任务的执行等操作,开发和维护更加简单和高效; 接收“调度中心”的执行请求、终止请求和日志请求等

image-20230202101025313
image-20230202104121240

xxl-job原理

执行器注册

执行器启动主要是把自己注册到调度中心然后保存在数据库(xxl_job_registry表),并定时发送心跳,保持续约。执行器正常关闭,也主动告知调度中心注销,这种是主动注册。

如果执行器网络故障,调度中心就不知道执行器的情况,如果把任务路由给一个不可用的执行器,就会导致任务失败。所以调度中心需要不断的对执行器探活(RocketMQ的NameServer 管理broker一样),调度中心会启动一个后台线程定时调用执行器接口,如果发现异常就下线。

调度中心和任务执行

  • JobRegistryMonitorHelper 不停的更新注册表,把超时的执行器剔除(每隔30s执行一次)

  • 创建线程池

    1. 调度器线程ScheduleThread:计算预读取的任务数(默认6000),然后while 循环不停的获取到期的任务
      时间轮线程池
    2. 获取任务锁:第一步获取数据库排它锁,如果没有成功说明其他的调度中心在加载任务
  • 查询任务:获取锁后, 查询任务

  • 调度任务

  • 任务触发,选择执行器:按照配置的路由策略,不通路由策略获取方式也不一样

  • 远程执行:拿到执行器之后,runExecutor 触发远程的执行器

  • 执行器处理远程调用,回调

时间轮可参考另一篇博客

时间轮算法(TimingWheel)是如何实现的?

任务超时

如果任务在指定的时间范围内没有返回结果,就不在等结果,抛出异常。

失败重试

如果任务执行失败,会更新在xxl_job_log日志表里。调度中心有个后台线程monitorThread。第一步就是查日志表里结果不是200的任务,为了防止集群下同时处理一个失败任务,用了数据库的乐观锁(版本号),如果失败重试次数>0,代表重试,就要重新触发。

//调度器启动:
JobFailMonitorHelper.getInstance().start();

故障转移

如果一个执行器挂了,就找另一个执行器执行,直到找到一个正常的执行器。

FAILOVER(I18nUtil.getString("jobconf_route_failover"), new ExecutorRouteFailover())
0

评论区