【开发经验】分布式任务调度——xxl-job

​ 之前了解了本地任务的调度方式,但是随着定时任务的越来越多,越来越复杂,单机压力压力越来越大,所以任务服务也需要做高可用。如果部署多台服务,就会存在任务谁来执行或者一个重复执行的问题。

​ 现在可以实现分布式任务调度的框架有很多,xxl-jobquartz等等。

​ quartz分布式任务调度是通过数据库锁实现的,实现思路简单,但是功能也简单,好多东西都需要自己二次开发。重点是需要简单的二次开发,而且没有可视化。

​ xxl-job上手很容器,有非常友好的可视化页面,功能强大,1分钟即可上手。至于如何解决服务高可用呢?如何解决重复执行问题呢?下面看。
在这里插入图片描述

1.xxl-job快速启动

  1. 下载源码:https://github.com/xuxueli/xxl-job
  2. 新建mysql数据库,初始化表结构,表信息在源码的doc/db/tables_xxl_job.sql目录下。在这里插入图片描述
  3. 下载源码后修改xxl-job-admin中的数据库配置。在这里插入图片描述
  4. 通过spring boot的方式启动即可。
  5. 浏览器通过http://localhost:8080/xxl-job-admin/进入登录页面,账号密码admin/123456

至此启动成功。进入可视化页面随便点点很简单的。

2.xxl-job基本使用

​ xxl-job可以分问调度中心执行器服务调度中心充当一个注册中心的作用,任务的执行信息通过调度中心写入到数据库中,执行器服务启动成功之后会再调度中心进行注册。调度中心通过http请求调用执行器服务的接口进行任务的调度,执行器执行成功之后返回成功信息给调度信息。

在这里插入图片描述在这里插入图片描述

路由策略选择:
FIRST(第一个):固定选择第一个机器;
LAST(最后一个):固定选择最后一个机器;
ROUND(轮询):;
RANDOM(随机):随机选择在线的机器;
CONSISTENT_HASH(一致性HASH):每个任务按照Hash算法固定选择某一台机器,且所有任务均匀散列在不同机器上。
LEAST_FREQUENTLY_USED(最不经常使用):使用频率最低的机器优先被选举;
LEAST_RECENTLY_USED(最近最久未使用):最久未使用的机器优先被选举;
FAILOVER(故障转移):按照顺序依次进行心跳检测,第一个心跳检测成功的机器选定为目标执行器并发起调度;
BUSYOVER(忙碌转移):按照顺序依次进行空闲检测,第一个空闲检测成功的机器选定为目标执行器并发起调度;
SHARDING_BROADCAST(分片广播):广播触发对应集群中所有机器执行一次任务,同时系统自动传递分片参数;可根据分片参数开发分片任务;

这样任务服务的高可用即可解决。

​ 到此可能就想,这样所有的任务就到调度中心了呀,调度中心需不需要高可用呢?如果调度中心部署多个,会不会有重复调度的问题呢?

调度中心是支持集群部署的。但是需要注意一些重点:

  • DB配置保持一致;
  • 集群机器时钟保持一致(单机集群忽视);
  • 建议:推荐通过nginx为调度中心集群做负载均衡,分配域名。调度中心访问、执行器回调配置、调用API服务等操作均通过该域名进行。

​ 基于数据库的集群方案,数据库选用Mysql;集群分布式并发环境中进行定时任务调度时,会在各个节点会上报任务,存到数据库中,执行时会从数据库中取出触发器来执行,如果触发器的名称和执行时间相同,则只有一个节点去执行此任务。

3.xxl-job特性

多种运行模式

​ xxl-job有调度中心,既然是一个调度中心,是不是可以不区分调度什么任务,就到时候触发事件就好啦?所以xxl-job有提供执行其他语言的运行模式。强不强!

GLUE模式(Java):任务以源码方式维护在调度中心;该模式的任务实际上是一段继承自IJobHandler的Java类代码并 "groovy" 源码方式维护,它在执行器项目中运行,可使用@Resource/@Autowire注入执行器里中的其他服务;
GLUE模式(Shell):任务以源码方式维护在调度中心;该模式的任务实际上是一段 "shell" 脚本;
GLUE模式(Python):任务以源码方式维护在调度中心;该模式的任务实际上是一段 "python" 脚本;
GLUE模式(PHP):任务以源码方式维护在调度中心;该模式的任务实际上是一段 "php" 脚本;
GLUE模式(NodeJS):任务以源码方式维护在调度中心;该模式的任务实际上是一段 "nodejs" 脚本;
GLUE模式(PowerShell):任务以源码方式维护在调度中心;该模式的任务实际上是一段 "PowerShell" 脚本;

GLUE模式(Java)

quartz框架或者一些其他的任务调度框架都可以实现简单的任务调度。但是xxl-job提供了更强大的特性。quartz使用的时候是服务中代码已经加载好了,无法做到实时添加任务调度方法。

​ 此模式可以通过web IDE,在浏览器中添加java代码进行执行。此功能超级变态,同时也超级危险。

​ 示例:

1.在执行器服务创建类UserService

package com.xxl.job.executor.service;

import org.springframework.stereotype.Service;

@Service
public class UserService {
    public String userName="张三";
}

创建成功之后启动执行器服务。服务启动成功UserService会被加载到spring IOC容器中。

2.创建任务

在这里插入图片描述

创建成功之后点即操作

在这里插入图片描述

进入页面之后即可随意编写代码,重点的是这里的代码是在数据库中,执行的时候是在执行器服务执行的。wbe IDE中复制如下代码,在调度器调度的时候即可输出张三。这样当然是很灵活,但是也很危险,如果调度器入口被别人获取了,那就可以为所欲为了。

package com.xxl.job.service.handler;

import com.xxl.job.core.log.XxlJobLogger;
import com.xxl.job.core.biz.model.ReturnT;
import com.xxl.job.core.handler.IJobHandler;
import org.springframework.beans.factory.annotation.Autowired;
import com.xxl.job.executor.service.UserService
public class LikuoJobHandler extends IJobHandler {

	@Autowired
  	private UserService userService;
	@Override
	public ReturnT<String> execute(String param) throws Exception {
		System.out.println(userService.userName);
		return ReturnT.SUCCESS;
	}

}

分片广播

该特性适用场景如:

  • 1、分片任务场景:10个执行器的集群来处理10w条数据,每台机器只需要处理1w条数据,耗时降低10倍;
  • 2、广播任务场景:广播执行器机器运行shell脚本、广播集群节点进行缓存更新等

参考资料

官网文档:https://www.xuxueli.com/xxl-job/

源码地址:https://github.com/xuxueli/xxl-job

猜你喜欢

转载自blog.csdn.net/qq_30285985/article/details/106820571