跳到正文

XXL-JOB 生产检查清单 ​

适用 XXL-JOB 2.4.x(2.3.x 行为基本一致)。SQL 以 MySQL 5.7/8.0 + 默认 schema 为准;默认值以对应版本官方文档为准。 只列不做会丢数据、会不可用、会查不出故障的动作;机制解释见本目录各篇正文。

上线前 ​

  • [ ] Admin 至少 2 实例、MySQL 有备份、全机配 NTP:多个 Admin 靠 xxl_job_lock 行锁串行认领,不选主;xxl_job_registry.update_time 由处理心跳的 Admin 本地时间写入,时钟偏差过大会互相判死。
  • [ ] 执行器注册三元组对齐:xxl_job_registry 用 (registry_group='EXECUTOR', registry_key=appname, registry_value=address) 定位;appname 必须与 xxl_job_group.app_name 一致,accessToken 与 Admin 一致,xxl.job.admin.addresses 带对上下文。容器/多网卡显式配 xxl.job.executor.ip 或 xxl.job.executor.address。
  • [ ] 调度参数按最坏执行时间定:cron 间隔大于最大执行时间;executor_block_strategy=SERIAL_EXECUTION(默认,队列无界)、executor_timeout=0(默认不限)、executor_fail_retry_count=0(默认不重试)、misfire_strategy=DO_NOTHING(默认,过期超过 5 秒不补)。
  • [ ] 业务幂等键先落地:XXL-JOB 是至少一次语义,失败重试、手动触发、/run 超时后的再次调度都会产生新日志和重复执行;用「业务日期 + 任务 + 维度」唯一键或状态机去重。
  • [ ] 日志表容量和清理策略确定:xxl.job.logretentiondays=30(默认),默认 schema 没有分区,清理是按主键分批 DELETE;磁盘到 80% 告警。需要 DROP PARTITION 只能自建按 trigger_time 分区的表,主键要改成 (id, trigger_time)。
  • [ ] 分片广播按「任务数 × 在线实例数」做容量规划:SHARDING_BROADCAST 给每个注册实例各发一次,shardTotal 等于当前在线实例数,不能单独配成固定值;多个分片任务错开 cron,Handler 入口加限流。

运行中 ​

  • [ ] 注册表年龄:SELECT registry_value, TIMESTAMPDIFF(SECOND, update_time, NOW()) AS age_s FROM xxl_job_registry WHERE registry_group='EXECUTOR' ORDER BY age_s DESC; 正常 0–30s,age_s > 90 告警;执行器下线后,自动注册的行在 90–120 秒内被剔除。
  • [ ] 结束回调积压:SELECT id, job_id, trigger_time FROM xxl_job_log WHERE trigger_code=200 AND handle_code=0 AND trigger_time < DATE_SUB(NOW(), INTERVAL 10 MINUTE); 结合 xxl_job_registry 判断执行器是否在线;handle_code=0 只表示没收到结束回调,不代表任务在跑。
  • [ ] 调度失败率:按 trigger_code=500 统计,看 trigger_msg;常见是地址为空、连接超时、Admin 触发线程池满(快池 max=200、慢池 max=100,队列 1000/2000)。
  • [ ] 执行积压:同一 jobId 的日志密集出现、Executor 日志显示单次耗时大于 cron 间隔;jstack <pid> 看 JobThread 队列是否堆满。SERIAL_EXECUTION 的队列无界,只加线程池无效。

故障时 ​

  • [ ] 所有任务不触发 / 调度线程阻塞 → SHOW PROCESSLIST、SELECT trx_id, trx_state, trx_started, trx_mysql_thread_id, trx_query FROM information_schema.innodb_trx WHERE trx_state='RUNNING'; → 找持有 xxl_job_lock 中 lock_name='schedule_lock' 行锁的会话并 KILL;不要 UPDATE xxl_job_lock 释放锁,也不要 TRUNCATE/DROP 该表。
  • [ ] 业务成功但页面一直「执行中」/ 结果丢失 → handle_code=0 超过 10 分钟、Executor 日志显示 Handler 成功、callbacklog/ 有文件或报错、地址已从注册表消失 → joblog_lost_fail 只表示状态未上报,不代表业务失败;先按业务键核对,再恢复 Admin 连通性让 callbacklog/ 的回调每 30 秒重试,不要直接重跑。
  • [ ] 执行器已下线但地址还在 → 查 xxl_job_registry 与 xxl_job_group.address_list;address_type=1 是手工录入,不会自动刷新和删除,过期地址会持续连接超时 → 能自动注册就不要手填。
  • [ ] 分片广播只产生一行日志 → 查 xxl_job_registry 是否有多个地址、xxl_job_group.address_list 是否包含全部实例、两个 xxl.job.executor.port 是否冲突、appname 是否一致 → 分片数等于在线实例数,少一台就少一个分片。
  • [ ] xxl_job_log 膨胀、磁盘告警 → 查 information_schema.TABLES 的 data_length、清理线程日志、xxl.job.logretentiondays → 恢复保留天数,紧急清理用分批 DELETE ... LIMIT 并先归档;默认表没有分区,不要直接 DROP PARTITION。

把一门技术讲透到既懂也会用