先说一下为什么会写这篇东西。定时任务这东西,做后端的基本都绕不过去,从最早直接用Thread.sleep循环、到Spring自带的@Scheduled,再到后来单机扛不住、引入分布式调度,每一步都是被业务逼出来的。我大概从xxl-job还叫xxl-job-2.0那会儿就开始用,中间换过Quartz、也试过别的平台,兜兜转转最后还是把大部分项目的定时任务都收敛到了xxl-job上。原因后面细说,先给你看结论:如果你需要在SpringBoot项目里做一套可靠、可视、支持分布式部署的定时任务调度,xxl-job是目前综合成本最低的选择之一。这篇文章会把服务端搭建、客户端集成、任务配置、运行模式、常见坑一次性讲完,照着做基本不会翻车。
1. 先搞清楚:为什么是xxl-job,而不是Quartz或Spring自带的定时任务
1.1 定时任务在业务里的常见痛点
很多项目一开始用@Scheduled,写起来确实爽,一行注解就完事。但等业务跑起来,问题就一个个冒出来了:
- 任务跑挂了没有任何通知,日志沉底,经常是业务方发现数据不对了才知道任务早停了;
- 任务执行时间不固定,想临时手动触发一次,得写接口或者改代码重启;
- 多实例部署时任务会重复执行,要么加分布式锁,要么单独起一个实例专门跑调度,很笨重;
- 任务执行耗时、成功失败情况全靠日志,没有一个直观的看板;
- 任务多了以后,代码里散落一堆定时任务,没人说得清线上到底跑了哪些、什么频率、什么参数。
这些问题在小项目里还能忍,一旦业务量上来,任何一个都能让你半夜爬起来查日志。Quartz能解决一部分问题,但它本身没有UI,分布式部署也要自己写扩展,学习成本不算低。
1.2 xxl-job核心优势拆解
xxl-job之所以被这么多项目采用,我认为核心是它直接命中上面这些痛点:
- 可视化控制台:任务的增删改查、暂停/启动、手动触发、日志查看,全在浏览器里操作,不用改代码;
- 分布式调度:调度中心支持集群部署,执行器支持水平扩展,任务在执行器之间自动分发;
- 运行模式丰富:支持Bean模式、GLUE模式(在线编写代码)、脚本模式等,灵活度高;
- 自带路由策略:第一个、最后一个、轮询、随机、故障转移、分片广播等,能覆盖绝大多数分发需求;
- 失败处理机制:支持调度失败重试、执行失败告警,还预留了邮件告警通道;
- 国内社区活跃:网上踩坑文章多,遇到问题基本搜得到解决方案。
一句话总结:xxl-job把定时任务从“裸奔”变成了“有管理后台、有监控、可动态调整”的完整方案。
1.3 整体架构和核心概念梳理
在动手搭建之前,有几个概念必须先理清楚,不然后面配置起来容易懵:
- 调度中心(Admin):一个独立的Web应用,负责任务的注册、调度、日志管理。可以简单理解成“大脑”;
- 执行器(Executor):跑实际业务代码的应用,也就是你的SpringBoot项目。它启动后会自动注册到调度中心,可以理解成“手脚”;
- 任务:在调度中心里配置的一条“什么时间执行什么方法”的记录;
- 调度:到了配置的时间点,调度中心向执行器发送HTTP请求,触发执行器执行对应的方法。
这里面最重要的一个点是:调度中心和执行器是通过HTTP接口通信的,不是RPC也不是消息队列。所以执行器不一定是Java项目,理论上任何语言只要实现xxl-job的协议都行。这也是xxl-job扩展性强的一个原因。
2. 服务端搭建:从源码到能跑起来的完整过程
2.1 环境准备清单
xxl-job调度中心本身是一个SpringBoot项目,所以环境要求其实不高:
- JDK 1.8 / 8+(我用的是JDK 8,稳妥,新版可尝试11或17但没太大必要);
- Maven 3.6+(用于编译源码);
- MySQL 5.7+(需要初始化数据库,用5.7或8.0都行);
- 一个顺手的IDE,IDEA或Eclipse均可。
我用的是2.4.1版本,官方推荐的稳定版,后面的步骤也基本以这个版本为例。如果你用更新的版本,配置项可能会略有差异,但整体思路一致。
2.2 源码下载和编译打包
xxl-job源码在GitHub上开源,直接clone下来:
git clone https://github.com/xuxueli/xxl-job.git如果你不需要改源码,其实编译整个项目有点浪费时间。建议直接进入xxl-job-admin子目录模块单独打包:
cd xxl-job/xxl-job-admin mvn clean package -DskipTests打包完成后,target目录下会生成一个xxl-job-admin-2.4.1-SNAPSHOT.jar。这个Jar就是调度中心,可以直接用。
提示:如果Maven依赖拉取比较慢,建议给仓库配置阿里云镜像,不然编译过程能急死人。
2.3 初始化数据库
xxl-job需要有一张数据库来存任务配置、调度日志、执行器注册信息等。源码里自带建表脚本,你需要手动执行一下。
脚本位置:/xxl-job/doc/db/tables_xxl_job.sql
用Navicat或命令行执行即可:
mysql -uroot -p < tables_xxl_job.sql执行完会在MySQL里创建一个名为xxl_job的库。默认有一张未命名的配置表xxl_job_group,以及任务表、日志表、锁表等若干张。建议先用默认库名,能少改很多配置。
2.4 修改配置文件并启动
进入xxl-job-admin的src/main/resources目录,找到application.properties,核心配置项如下:
server.port=8080 spring.datasource.url=jdbc:mysql://127.0.0.1:3306/xxl_job?useUnicode=true&characterEncoding=UTF-8&serverTimezone=Asia/Shanghai spring.datasource.username=root spring.datasource.password=123456需要改成你自己MySQL的连接信息。如果你改了库名,这里也要对应改。其他配置项默认就行,等熟悉了再去调。
然后启动:
java -jar target/xxl-job-admin-2.4.1-SNAPSHOT.jar看到日志里出现“启动成功”字样就可以访问了。浏览器打开:http://localhost:8080/xxl-job-admin,默认账号密码是admin/123456。
2.5 初次登录与基础配置
登录后先别急着配任务,有几个地方我建议你先看一下:
- 执行器管理:这里会显示所有接入的SpringBoot应用,启动执行器后会自动注册在这里;
- 调度日志:所有任务调度的执行记录都在这里,排查问题最主要看这个;
- GLUE编辑器:如果你打算用在线代码模式,任务详情页里就能进入编辑器,后面细说。
到这里,调度中心的搭建就完成了。接下来是最关键的一步——怎么把SpringBoot项目接入进来,把业务方法暴露成可调度的任务。
3. SpringBoot客户端集成:一步步把任务跑起来
这一部分是重点,集成步骤非常多,网上很多教程在客户端这块都写得过于简略,我这里从头到尾过一遍。
3.1 引入依赖
在你的SpringBoot项目的pom.xml中加入xxl-job的依赖:
<dependency> <groupId>com.xuxueli</groupId> <artifactId>xxl-job-core</artifactId> <version>2.4.1</version> </dependency>3.2 配置application.yml
在SpringBoot项目的application.yml里增加执行器相关配置:
xxl: job: admin: addresses: http://localhost:8080/xxl-job-admin accessToken: default_token executor: appname: my-springboot-executor address: ip: port: 9999 logpath: /data/applogs/xxl-job/jobhandler logretentiondays: 30逐个解释一下这几个配置项的含义:
admin.addresses:调度中心地址,多个地址用逗号分隔;accessToken:通信令牌,调度中心和执行器两边要一致,否则通信会被拒绝。默认是default_token,如果你在调度中心配了别的,这里必须改成一致;executor.appname:执行器名称,在调度中心注册时用的名字,后面添加执行器时要对应;executor.port:执行器端口,用于接收调度中心的HTTP请求。注意不要和SpringBoot项目本身的端口冲突;executor.logpath:任务执行日志的存放路径,这个目录要存在且有写权限;executor.logretentiondays:日志保留天数,默认30天自动清理。
3.3 配置XxlJobSpringExecutor
在SpringBoot启动类或者任意Configuration类里注册XxlJobSpringExecutor的Bean:
@Configuration public class XxlJobConfig { @Value("${xxl.job.admin.addresses}") private String adminAddresses; @Value("${xxl.job.accessToken}") private String accessToken; @Value("${xxl.job.executor.appname}") private String appname; @Value("${xxl.job.executor.port}") private int port; @Bean public XxlJobSpringExecutor xxlJobExecutor() { XxlJobSpringExecutor xxlJobSpringExecutor = new XxlJobSpringExecutor(); xxlJobSpringExecutor.setAdminAddresses(adminAddresses); xxlJobSpringExecutor.setAppname(appname); xxlJobSpringExecutor.setPort(port); xxlJobSpringExecutor.setAccessToken(accessToken); return xxlJobSpringExecutor; } }这里有个小坑:如果你不想用配置文件里的值,也可以直接在代码里写死,但不推荐。因为环境不同(本地、测试、生产)调度中心地址和令牌很可能不一样,写成配置方便部署管理。
3.4 编写第一个任务Handler
在SpringBoot项目中新建一个类,写一个方法,加上@XxlJob注解,这个方法就变成了一个可被调度中心调度的任务:
@Component public class SampleXxlJob { private static final Logger logger = LoggerFactory.getLogger(SampleXxlJob.class); @XxlJob("demoJobHandler") public void demoJobHandler() throws Exception { logger.info(">>>>>>>>>> xxl-job demo task started"); System.out.println("hello xxl-job, this is a demo task"); logger.info(">>>>>>>>>> xxl-job demo task finished"); } }注意三点:
- 类必须被Spring容器管理,也就是加上
@Component或@Service注解,否则执行器扫描不到; - 方法必须加
@XxlJob注解,注解的值就是任务Handler名称,后面在调度中心配置任务时要对应; - 方法必须是
public void,可以有参数也可以没有参数,如果有参数,传的是String类型,可以接收调度中心传过来的JSON字符串。
到这里,SpringBoot端的代码已经写完了。启动项目,如果一切正常,日志里会看到xxl-job register executor success,并且调度中心的“执行器管理”页面里会出现一个名为my-springboot-executor的执行器。
3.5 在调度中心配置任务并执行
调度中心配任务的过程,很多人第一次会摸不着头脑。跟着下面步骤走:
- 在“执行器管理”页面,确认执行器已注册。如果没有,点“新增”手动添加一个,AppName填
my-springboot-executor,名称随意; - 进入“任务管理”页面,点“新增”;
- 配置任务信息,重点字段如下:
执行器:下拉选择刚刚注册的执行器;任务描述:写清楚这个任务是干嘛的;调度类型:选Cron,填一个Cron表达式,比如每隔30秒执行一次就填0/30 * * * ? *;运行模式:选Bean;JobHandler:填demoJobHandler,和代码里的注解名一致;阻塞处理策略:选单机串行,后面会细讲;路由策略:如果只有一个执行器,选第一个或轮询都行。
保存后,在任务列表里点击“操作”列的“启动”,任务就开始按Cron调度了。如果想立即跑一次,不等到时间点,点“执行一次”按钮。
去执行器项目的控制台看一下,如果打印了hello xxl-job, this is a demo task,说明整条链路已经通了。
到了这一步,从服务端搭建到客户端集成的最小闭环已经完成了。
4. 运行模式与调度策略:这块搞明白了才算真正会用xxl-job
很多人把任务配完能跑就觉得完事了,但实际上对运行模式和调度策略的理解,决定了你在复杂场景下能不能把xxl-job用好。这一章详细拆一遍。
4.1 BEAN模式与GLUE模式的区别
xxl-job的运行模式在配置任务时必选,最常用的是这两种:
- BEAN模式:任务调度的是Spring容器里某个Bean的某个方法,对应代码里用
@XxlJob注解标记的方法。这种方式的好处是业务逻辑在代码里,有版本管理、可以单测,适合正式项目; - GLUE模式:任务逻辑直接以代码片段形式存在调度中心里,调度中心附带一个在线编辑IDE,修改立即生效,不用重新部署应用。适合临时任务、运营配置类任务、快速热更新场景。
我个人的经验是:正式任务全部用BEAN模式。GLUE模式虽然方便,但代码在数据库里,时间一长没人维护,特别容易变成“黑盒”。曾经接手过一个项目,调度中心里躺着十几个GLUE任务,最早的一个是两年前的,业务方都不记得是干嘛的了,非常被动。
4.2 路由策略怎么选
路由策略是针对“有多个执行器实例都在跑同一个任务”时,调度中心该把任务分发给哪个实例的问题。常用场景如下:
| 策略 | 含义 | 适用场景 |
|---|---|---|
| 第一个/最后一个 | 固定发给第一个/最后一个实例 | 单活任务,比如每天只跑一次的报表任务 |
| 轮询 | 多个实例依次轮流 | 多活且无状态的任务,比如批量发送短信 |
| 随机 | 随机选一个 | 负载均衡要求不高的场景 |
| 故障转移 | 发一个失败的实例自动换另一个 | 对实时性要求高的任务 |
| 分片广播 | 所有实例都执行,带分片参数 | 需要把数据分批处理的大批量任务 |
重点说一下分片广播。这是xxl-job非常实用的一个策略:比如你有100万条数据要批量处理,部署了5个执行器实例,选择分片广播后,每个实例都会执行任务,但会收到不同的分片参数(shardIndex和shardTotal),你可以根据当前是第几个实例/总共几个实例算出自己负责哪些数据,从而实现分布式并行处理,大大提升任务吞吐量。
第一次接触分片概念可能有点绕,举个例子:假设清理临时文件,5个实例分片广播,每个实例通过XxlJobHelper.getShardIndex()拿到自己的编号(0-4),通过getShardTotal()拿到总实例数5,然后只处理文件ID % 5 == 自己编号的那部分文件。这样100万个文件每个实例只用处理20万,效率直接翻几倍。
4.3 阻塞处理策略
当任务调度时间到了,但上一个任务还没执行完,这时候会触发阻塞处理策略。三个选项的区别必须搞清楚:
- 单机串行:新任务排队等,上一个执行完才继续,适合大多数场景;
- 丢弃后续调度:新任务来了发现上还没执行完,直接丢,适合对数据时效性不强、怕重复处理的任务;
- 覆盖之前调度:新任务开始执行时,把上一个还没执行完的任务终止掉,适合永远只需要保留最新一次执行结果的任务。
实际项目里,单机串行覆盖了90%的场景。覆盖之前调度用起来要小心,因为强制终止线程可能导致资源没释放。
5. 常见问题与排查思路实录:我在实际项目中踩过的坑
文档上的东西都好说,真到出问题时才是最考验人的。这里把我这几年用xxl-job遇到的比较典型的问题列出来,附上排查思路和解决办法。
5.1 调度中心启动失败
现象:执行java -jar启动xxl-job-admin,日志报一堆SQL异常或数据源连不上。
分析:大概率是MySQL连接信息配置不对,或者没执行建表脚本。xxl-job启动时要访问数据库,如果表不存在会初始化失败,但它不会自动建表,必须先手动执行SQL脚本。
解决办法:
- 确认
application.properties里的数据库URL、用户名、密码正确; - 确认
xxl_job库是否存在,登录MySQL执行show databases;看看; - 如果库不存在或表不全,重新执行
tables_xxl_job.sql。
5.2 执行器启动成功但调度中心看不到
现象:SpringBoot项目启动正常,日志也显示注册成功,但调度中心的“执行器管理”页面就是没有新的执行器。
分析:最常见的原因是执行器管理里没有对应AppName的执行器配置。调度中心的执行器列表是需要手动添加的,不会自动出现。
解决办法:在“执行器管理”页面点“新增”,AppName填和application.yml里xxl.job.executor.appname一致的值(比如my-springboot-executor),保存后再刷新页面,就能看到执行器了,状态会是“已注册”。
另一个原因是accessToken两边不一致,日志里会提示JobController receive job handler error之类的问题,去检查调度中心和客户端的Token是否一致。
5.3 任务触发成功但业务没执行
现象:调度中心日志显示任务“调度成功”,但执行器应用的日志里没有对应打印。
分析:这个问题比较隐蔽,大多数情况是JobHandler名字对不上。调度中心配置任务时,JobHandler字段填的名字必须和代码里@XxlJob("xxxx")注解的值完全一致,大小写、空格都要一致。
还有一个容易忽略的点:注册的是多个执行器,路由策略选的第一个,但第一个实例可能不是你的本地实例,所以看起来像是“没执行”。
解决办法:先在调度日志里看“执行成功”的机器IP是多少,再到那台机器上看日志。如果是JobHandler名字问题,把调度中心的配置值和代码注解值改成一致即可。
5.4 任务执行超时或被误杀
现象:任务跑了很久,调度中心显示执行失败,但应用日志显示任务还在继续执行。
分析:xxl-job默认有一个超时时间(30秒),超过这个时间还没执行完,调度中心会记录失败。但实际业务场景里,很多批量处理任务都要跑几分钟甚至更久。
解决办法:两个方向。一是如果业务允许,把任务拆小,用分片广播并行处理;二是在xxl-job任务配置页面调大“超时时间”参数(单位是秒,可以设成0表示不设超时)。另外注意,长时间执行的任务最好用异步处理或独立线程池,尽量避免阻塞执行器的业务线程,因为执行器本身还要响应其他任务的调度请求。
5.5 线上问题速查表
这里整理一份我平时排查问题用的速查表,照着顺序检查,大多数问题都能定位:
| 症状 | 第一步检查 | 第二步检查 | 常用解决办法 |
|---|---|---|---|
| 调度中心登录不上 | 端口是否被占用 | MySQL是否连通 | 改端口,确认数据库配置 |
| 执行器日志没有输出 | 检查执行器路径有无权限 | 检查logback配置 | 给目录加权限或改路径 |
| 任务调度不触发 | Cron表达式是否正确 | 任务是否“启动”状态 | 用在线Cron生成器校验 |
| 任务执行重复 | 路由策略是否选了广播 | 是否用了统一的分布式锁 | 改用单机串行 |
| 日志报权限异常 | 执行器用户名是否文配置 | 调度中心是否加白名单 | 使用默认token |
5.6 日志查看与定位技巧
xxl-job的日志分两层:调度中心日志和执行器日志。
调度中心日志在“调度日志”页面里可查看,可以看到任务的触发时间、执行结果、调度耗时、执行耗时。如果任务执行失败,点“日志”按钮会跳到执行器里的实际日志文件,这是定位问题的主入口。
执行器日志就是应用日志,但xxl-job把每次任务执行记录在executor.logpath配置的目录下,文件名带JobId和执行时间,非常清晰。重点提醒一下,如果执行器跑在容器或者K8s里,logpath要配置成持久化目录,不然Pod重启日志就丢了,很难排查历史问题。
6. 从demo到生产环境:一些值得改进的细节
如果你按前面的步骤把Demo跑通了,下面这些细节是从“能用”到“好用”的关键。
6.1 调度中心高可用:集群部署
生产环境调度中心不能是单点,否则调度中心挂了任务全部停摆。xxl-job官方支持调度中心集群部署,做法很简单:
- 把打包好的Jar在多台机器上分别启动;
- 数据库共用一个MySQL库;
- 通过Nginx或负载均衡把请求分发给多个调度中心节点。
注意,调度中心集群要求数据库必须共用,因为所有节点的状态都存在数据库里。另外,调度中心分别启动后,执行器端的admin.addresses配多个地址即可,比如:
xxl: job: admin: addresses: http://192.168.1.10:8080/xxl-job-admin,http://192.168.1.11:8080/xxl-job-admin6.2 执行器水平扩展与优雅停机
执行器部署多实例后,调度中心会自动在多个实例间做负载分发。但这里踩过一个大坑:执行器是临时注册的,默认30秒上报一次心跳,如果实例宕机,调度中心最多要等30秒才能感知并摘除节点。这期间调用方可能会调到已宕机的实例上。
解决办法:配置好心跳时间(xxl.job.executor.registry-interval)和优雅停机。SpringBoot项目的优雅停机配置如下:
spring: lifecycle: timeout-per-shutdown-phase: 30s同时在执行器关闭前手动注销节点:
@PreDestroy public void destroy() { xxlJobExecutor().destroy(); }这样在发布重启的时候,调度中心能较快感知实例下线,减少任务分发到“将死”实例的概率。
6.3 动态参数传递:让定时任务更灵活
xxl-job支持在任务配置时填写“任务参数”,这个参数会以JSON字符串的形式传给@XxlJob注解方法的入参。比如你可以给同一套代码,配置两条任务:
- 任务A:参数
{"type":"invoice","date":"2024-01-01"} - 任务B:参数
{"type":"receipt","date":"2024-01-01"}
代码里通过XxlJobHelper.getJobParam()获取参数,然后解析JSON做对应的业务处理。这样一条写死的任务逻辑,因为参数不同可以复用,大大提高了任务的可配置性。
实际业务里,我经常用这个功能来做“补数据”场景。不需要改代码,直接在调度中心手动触发一次,带上指定日期参数,就把某一天的数据重算了一遍。这个功能在运营活动、数据修复时尤其好用。
6.4 任务监控与告警:别等业务方来找你
xxl-job虽然自带告警接口,但默认需要自己实现JobAlarmer接口或者配置邮件告警。我这里更推荐的做法是:把xxl-job的调度结果主动同步到你们自己现有的监控体系。
具体做法不复杂:
- 在执行器的任务方法里,把执行结果、耗时写到日志;
- 用日志采集工具(比如ELK、Loki)收集执行器日志;
- 配置关键字告警,比如“ERROR”“Task Failed”等。
如果你没有现成的监控体系,可以先从最简单的方式做起:写一个定时任务(也可以用xxl-job本身),定期扫描调度中心的失败日志表,发现失败任务就往钉钉/飞书群里发通知。等业务规模再大一些,再考虑接入专业监控平台。
7. SpringBoot集成xxl-job的常见问题快问快答
结合搜索热词,把平时群里大家问得比较多的问题也一并回答了。
7.1 SpringBoot2.x和SpringBoot3.x兼容吗?
官方说明是支持到SpringBoot2.x为主,SpringBoot3.x需要自己适配,主要是javax到jakarta的包路径切换问题,因为xxl-job-core内部用到了Servlet API。目前2.4.x版本对SpringBoot3.x的兼容不算特别好,新项目如果用SpringBoot3,建议先升级试试,确认没有兼容问题再用。
7.2 @Scheduled和xxl-job能同时用吗?
可以同时使用。但一般不建议同一个项目里两种方式混用,因为维护上容易混乱。如果你已经用了xxl-job,建议逐步把@Scheduled迁移过去,统一管理入口。
7.3 xxl-job和Quartz怎么选?
如果项目规模小、任务量不大、也不需要可视化管理,@Scheduled和Quartz就够了。但只要任务超过10个、或者需要多实例部署、或者运营和产品需要经常手动触发任务,直接用xxl-job最省心。Quartz本身是个好框架,但运维和可观测性这块,确实是xxl-job的强项。
7.4 任务执行失败会重试吗?
xxl-job默认失败不会重试,需要手动在任务配置里设置“失败重试次数”。注意这个重试是调度中心重新触发一次任务,不是执行器内部重试。如果业务对失败重试有特殊要求(比如需要退避),建议在代码里自己实现。
7.5 执行器是SpringBoot项目,但不想启动Web服务器怎么办?
xxl-job的执行器本质上是一个内嵌的Netty HTTP服务,和SpringBoot的Web容器是分开的。如果项目里不需要Web功能,可以在pom里排除自带的Web依赖,但执行器端口依然会监听,不影响任务调度。
7.6 怎么保证任务在集群下不重复执行?
两种情况区分:一是选择路由策略为“第一个”或“随机”,这种天然只有一个实例执行,不存在重复;二是选“分片广播”,那每个实例执行的数据范围必须按分片参数隔离,代码里要有% shardTotal之类的逻辑,否则重复是必然的。
我个人在这个问题上补一刀:不管路由策略是什么,任务处理的核心步骤尽量做幂等。比如用数据库唯一索引、Redis锁,即使极端情况下重复触发,也不会产生脏数据。这个习惯能让你省掉很多线上事故。
8. 从搭建到运维的经验之谈
文章写到这里,该讲的步骤和技术点都讲完了。最后分享一点我个人的体会。
刚开始用xxl-job的时候,我其实有点“嫌弃”它只是把Quartz包了一层外壳,但实际用久了才意识到:定时任务这一层,真正的难点不是“触发”,而是“管理”和“可观测”。xxl-job的价值恰恰体现在这里——它让你对线上所有定时任务的状态、执行记录、成功率一目了然,而这一点在业务复杂度上来之后几乎成了刚需。
从一个中型项目的角度看,xxl-job的服务端部署一次之后基本不用管,平时主要工作是执行器集成和新任务的配置,这些都只需要在控制台点几下就能完成,对开发者的技术负担非常小。
最后分享两个小技巧。一个是任务命名规范,建议格式为业务模块_动作_描述_日期,比如order_statistics_daily_2024,这样在任务列表里一眼就能看出是哪个业务、做什么、什么频率,排查问题时体验完全不一样。另一个是拿到新项目先看调度中心的任务列表,这比翻代码更快了解项目跑着哪些定时任务,尤其是接手老项目的时候,这一步能帮你快速摸清业务里有哪些“定时动作”。
希望这篇文章能让你把xxl-job顺利跑起来,少踩一些我当年踩过的坑。后面有时间的话,我打算再写一篇关于xxl-job二次开发的内容,比如自定义告警通道、扩展执行器的鉴权逻辑,欢迎持续关注。