Xxl-Job执行器自动注册是怎么做的?

开发 前端
相信使用过 xxl-job 的众多开发同学里,有很多人新增执行器时都是跟我们一样选择自动注册。这个操作在容器化部署来临之前没什么问题,但是随着后来 docker 容器的流行,线上服务大多以容器方式放行。

一、xxl-job 执行器自动注册 ip 错误

先说一下问题发生的场景,这个问题来自我们测试 xxl-job 后管新增一个执行器时,新增执行器时选择的是自动注册机制,也就是由 xxl-job 自动填写我们的执行器 ip 地址。

相信使用过 xxl-job 的众多开发同学里,有很多人新增执行器时都是跟我们一样选择自动注册。这个操作在容器化部署来临之前没什么问题,但是随着后来 docker 容器的流行,线上服务大多以容器方式放行。

容器的 ip 都是虚拟 ip,不代表物理机真实通信地址的 ip,这里就有一个问题,如果 xxl-job 后管跟执行器不在同一个服务器部署,并且执行器自动注册提交的是容器 ip,那么就会产生定时任务执行失败的问题,因为 xxl-job 后管调用不通执行器。

这里给大家画一个 xxl-job 调用执行器的示意图,方便大家理解,

调用流程调用流程

给大家讲一下示意图:

1.xxl-job 执行器在启动时会向 xxl-job 后管提交当前服务器 ip,获取逻辑在 com.xxl.job.core.util.IpUtil#getIp 方法中,这个方法在最新版本里默认优先使用 JDK 提供的 InetAddress.getLocalHost() 方法获取本机 ip。获取不到的话再使用 JDK 提供的 NetworkInterface.getNetworkInterfaces() 方法遍历本机网卡获取 ip。

InetAddress.getLocalHost() 的一些坑:

  • 在 Linux 环境通过获取 /etc/hosts 和 /etc/resolv.conf 文件内容,如果在 /etc/hosts 文件内容中没有匹配到对应的 ip 地址,则通过 /etc/resolv.conf 中配置的 DNS 地址,向 DNS 服务器发出域名解析请求;
  • 如果访问 DNS 服务存在性能问题;
  • InetAddress.getLocalHost() 实现中还加了 synchronized 锁,并发环境中会影响性能。

2.调用 xxl-job 后管提供的 api/registry 接口,传递 xxl-job 执行器名称以及通信地址。

3.xxl-job 后管触发定时任务时,会调用 xxl-job 执行器提供的 /run 接口来执行对应任务。

在上面流程中,因为第二步提交的 xxl-job 执行器通信地址错误,因而导致第三步执行失败。那么怎么解决这个问题嘞,其实很简单,xxl-job 后管使用手动注册填写可以联通的执行器地址即可。

二、xxl-job执行器自动注册流程

xxl-job 执行器的自动注册流程其实很简单,这里给大家梳理一下,

自动注册、移除流程自动注册、移除流程

三、执行器注册

客户端在引入 xxl-job 执行器启动时,xxl-job 执行器会启动 ExecutorRegistryThread 线程,

图片图片

这个线程是专门来做执行器注册的,它会每隔 30 秒调用 xxl-job 后管的 /api/register 接口提交执行器地址和名称。

xxl-job 后管收到执行器的注册信息后,会通过 registryOrRemoveThreadPool 线程池异步保存执行器信息并发送成功响应。

图片图片

registryOrRemoveThreadPool 线程池会判断是否已经存在当前执行器注册记录,不存在就新建,存在就更新执行器最新注册时间。

所以当我们在 xxl-job 后管新增执行器,选择自动注册的时候,执行器的地址就是这么来的。

四、执行器移除

移除有两个方式,一种是正常结束 xxl-job 执行器,比如停止应用程序,xxl-job 执行器就会调用 /api/registryRemove 接口用来移除当前执行器注册信息。还有一种 xxl-job 后管启动的 registryMonitorThread 线程自动检测注册时间已经超期的执行器注册信息。

图片图片

registryMonitorThread 线程会查询所有自动注册类型的执行器,然后查询它们对应的注册记录最新时间是否超期,在xxl-job中,这个超期时间是90秒。超过 90 秒后就会移除执行器。

移除时会同时删除 xxl_job_group、xxl_job_registry 表的执行器信息。

四、最后关于IpUtil.getIp() 的一点思考

其实查看 xxl-job 执行器获取执行器 ip 的 com.xxl.job.core.util.IpUtil 文件的提交历史,我们可以发现,早在 18 年就有人发现了这个问题,并向官方提交了 issue 和 pr,并且这个 pr 也被官方认可合并了。

图片图片

然而官方在 2020 的提交记录中又修改了 com.xxl.job.core.util.IpUtil.getIp 方法,

图片图片

把本来放到方法末尾的 InetAddress.getLocalHost() 方法又提到了方法开头。。。


看了提交历史和上面关于InetAddress.getLocalHost() 一些坑的朋友,此处应该一脸疑问。。。

这里就暂且当作者基于某种考虑这么做,至于为什么,我已经去 github 提交了 issue,帮大家问了。。。

图片图片

责任编辑:武晓燕 来源: 程序员wayn
相关推荐

2023-11-07 07:56:40

2020-07-17 09:33:39

CPU内存调度

2022-03-26 17:13:22

ElasticJobxxl-job分布式

2022-09-23 13:57:11

xxl-job任务调度中间件

2024-11-06 18:01:15

分布式任务调度组件

2024-08-27 09:34:24

2023-01-04 09:23:58

2023-11-30 22:06:43

2024-09-09 08:11:12

2021-12-26 19:07:51

MySQL存储容器

2024-07-31 08:18:40

2012-05-24 14:58:55

开源代码

2023-06-27 07:44:53

xxl-job分布式任务调度平台

2022-12-29 08:32:50

xxl-job缓存Schedule

2021-12-26 00:03:27

响应式编程异步

2022-01-27 08:44:58

调度系统开源

2017-07-20 13:11:46

Code ReviewPR评审

2011-03-11 09:53:46

FacebookMySQL

2022-04-29 08:41:40

开发应用程序执行器

2022-05-05 08:43:22

SQL执行器参数
点赞
收藏

51CTO技术栈公众号