其他分享
首页 > 其他分享> > 记一次xxl-job执行器Online机器地址(注册节点)加倍问题

记一次xxl-job执行器Online机器地址(注册节点)加倍问题

作者:互联网

文章目录

背景

最近需要将任务改为分布式调度,而任务调度使用的是开源的xxl-job

改为分布式调度也很简单

  1. 首先获取当前节点和总节点数量
				// 当前分片
        int shardIndex = XxlJobHelper.getShardIndex();
        // 分片总数
        int shardTotal = XxlJobHelper.getShardTotal();
  1. 获取业务任务取模处理
select * from test_job where mod(id, #{shardTotal}) = #{shardIndex}
  1. 修改任务路由策略为分片广播
    在这里插入图片描述

问题

遇到的问题是docker容器中明明只是部署了两个节点,但是查看调度中心中执行器中的Online 机器地址却有四个
image-20210929193141767
而且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的配置
image-20210928211229740

会发现指定了initMethod方法为start方法,这里会导致一个什么问题呢?
XxlJobSpringExecutor本身是实现了SmartInitializingSingleton接口
afterSingletonsInstantiated方法本身就调用了父类(XxlJobExecutor)的start方法,如果再执行initMethod指定的start,就会导致调用两次start方法(初始化bean一次,bean初始化完又调用一次),xxl 执行器就会注册两次导致执行器注册数量不对。

解决方式

这里就真相大白了,就是配置不对,需要将配置文件中的initMethod给干掉

总结

其实看源码大致就是这么一个思路,解决了一个什么问题并不重要,重要是解决问题的思路。其实我这里是有看源码看到最后如何从xxl-job-admin注册节点获取数据,无非基于自己实现的http发生了一个请求,最终写到数据库中的xxl_job_registry表中

核心源码可以截图给大家看看
在这里插入图片描述

在这里插入图片描述

找到调用url后我们直接项目中搜索registryRemove
在这里插入图片描述
最终也是调用dao存储
在这里插入图片描述

在这里插入图片描述

标签:执行器,XxlJobSpringExecutor,job,源码,Online,xxlJobSpringExecutor,xxl
来源: https://blog.csdn.net/qq_42651904/article/details/120555995