-
背景
-
问题
-
排查
-
解决方式
-
总结
背景
最近需要将任务改为分布式调度,而任务调度使用的是开源的xxl-job
改为分布式调度也很简单
-
首先获取当前节点和总节点数量
// 当前分片
int shardIndex = XxlJobHelper.getShardIndex();
// 分片总数
int shardTotal = XxlJobHelper.getShardTotal();
-
获取业务任务取模处理
select * from test_job where mod(id, #{shardTotal}) = #{shardIndex}
问题
遇到的问题是docker容器中明明只是部署了两个节点,但是查看调度中心中执行器中的Online 机器地址却有四个而且IP地址很奇怪,就是同一个ip地址注册了两个执行器,不同的是一个是9999端口,一个是10000端口。
排查
为了解决这个问题,就去github下载了和版本匹配的源码2.3版本,在本地搭建了一个简单的运行环境,然后去看这个注册节点是如何统计的。
xxl的源码比较简单,先执行需要的sql脚本,修改数据库配置然后启动
xxl-job-admin
然后在启动sample-springboot
这个项目。
然后通过我们分片参数获取方式作为入口,进行源码分析
int shardIndex = XxlJobHelper.getShardIndex();
点进去会发现最终获取的是
XxlJObContext
中的shardIndex
属性,然后我们看看shardIndex
属性是如何赋值的
这里整个链路追踪有点长。最后追到这里而
EmbedServer
类是继承了Netty的SimpleChannelInboundHandler
。所以这里很明显shardIndex
就是xxl-job-admin
来的那么如果来的呢?
肯定是启动的时候调用来的,我们就从配置文件入手,一般我们配置是像这样配置一个XxlJobSpringExecutor
@Bean
public XxlJobSpringExecutor xxlJobExecutor() {
logger.info(">>>>>>>>>>> xxl-job config init.");
XxlJobSpringExecutor xxlJobSpringExecutor = new XxlJobSpringExecutor();
xxlJobSpringExecutor.setAdminAddresses(adminAddresses);
xxlJobSpringExecutor.setAppname(appname);
xxlJobSpringExecutor.setAddress(address);
xxlJobSpringExecutor.setIp(ip);
xxlJobSpringExecutor.setPort(port);
xxlJobSpringExecutor.setAccessToken(accessToken);
xxlJobSpringExecutor.setLogPath(logPath);
xxlJobSpringExecutor.setLogRetentionDays(logRetentionDays);
return xxlJobSpringExecutor;
}
我们看源码会发现XxlJobSpringExecutor
实现了spring的SmartInitializingSingleton
接口
而SmartInitializingSingleton
接口的方法afterSingletonsInstantiated
在bean初始化完会执行。我们看看afterSingletonsInstantiated
的方法可以看到调用了一个
start()
方法,我们进入start()
方法会发现又调用一个initEmbedServer
方法
进入方法initEmbedServer
我们会发现有一个获取执行器端口的方法我们进入获取端口的方法
会发现默认注册的端口是9999,如果端口占用了就会+1,变成10000。
这里就和我们上面类似,但是上面是注册了9999和10000端口,那么这里是不是说我们的一个执行器注册了两次呢?
然后我看我们项目中XxlJobSpringExecutor
的配置
会发现指定了initMethod
方法为start
方法,这里会导致一个什么问题呢?XxlJobSpringExecutor
本身是实现了SmartInitializingSingleton
接口afterSingletonsInstantiated
方法本身就调用了父类(XxlJobExecutor
)的start
方法,如果再执行initMethod
指定的start
,就会导致调用两次start
方法(初始化bean一次,bean初始化完又调用一次),xxl 执行器就会注册两次导致执行器注册数量不对。
解决方式
这里就真相大白了,就是配置不对,需要将配置文件中的initMethod
给干掉
总结
其实看源码大致就是这么一个思路,解决了一个什么问题并不重要,重要是解决问题的思路。其实我这里是有看源码看到最后如何从xxl-job-admin
注册节点获取数据,无非基于自己实现的http发生了一个请求,最终写到数据库中的xxl_job_registry表中

找到调用url后我们直接项目中搜索registryRemove
最终也是调用dao存储

原文始发于微信公众号(小奏技术):记一次xxl-job执行器Online机器地址(注册节点)加倍问题
版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。
文章由极客之音整理,本文链接:https://www.bmabk.com/index.php/post/30295.html