点击上方名片关注我,让你开发少踩坑
还是在部署xxljob的时候,遇到的一个坑,其他基本操作按照官方文档来,不会出现什么问题,我这里列出的都是一些文档上没提到的可能会忽略的点。本文适合准备或者已经接入xxljob或者其他分布式调度平台的朋友查看
出现的坑
xxljob部署在docker容器中(以下简称服务端)
业务应用的测试环境也部署在docker容器中(以下简称客户端)
客户端整合了xxljob后,在本地启动是可以和服务端通信的,客户端也能够在服务端注册成功。
但是当我把业务应用的新代码部署到测试环境上的时候,就报错了
Full authentication is required to access this resource
分析思路
一开始以为是spring安全策略配置的问题,虽然疑惑为什么本地没问题,但还是尝试把报错的api放入了白名单,重新部署。
结果又报错404,客户端依旧未注册成功
这下点醒了我,说明是服务端与客户端通信不成功,不成功的原因就是因为这个api,而这个api应该是服务端发送给客户端的一个心跳检测,这个请求本应该是打到集成在业务中的客户端,但看日志情况,却是打到了业务应用中。
说明ip没问题,但很可能端口出了问题
正常应该是这二者通信
解决办法
于是又看了以下文档和具体通信代码,结合本地测试可以,docker中不可以的现状,解决了问题(具体文档就不贴了,相信看这篇文章的朋友肯定已经明白基本配置了)
将客户端配置类改为
@Bean
public XxlJobSpringExecutor assetsXxlJobExecutor() {
log.info(">>>>>>>>>>> xxl-job config init.");
XxlJobSpringExecutor xxlJobSpringExecutor = new XxlJobSpringExecutor();
xxlJobSpringExecutor.setAdminAddresses(adminAddresses);
xxlJobSpringExecutor.setAppname(appname);
xxlJobSpringExecutor.setAccessToken(accessToken);
xxlJobSpringExecutor.setLogPath(logPath);
// xxlJobSpringExecutor.setIp(ip); 这行注释掉,否则address会默认取ip拼接port
// 这个port和address中的port是不同的,这是重点
xxlJobSpringExecutor.setPort(innerPort);
// 正常示例不传address,直接取ip:port作为address字段
xxlJobSpringExecutor.setAddress("http://{ip_port}/".replace("{ip_port}", IpUtil.getIpPort(ip, externalPort)));
return xxlJobSpringExecutor;
}
之所以这么改,是因为涉及到了两个端口
docker容器启动的时候,会有一个容器的虚拟端口,比如这里是9999,也就是上文中的innerPort,这个端口是客户端启动的时候需要的一个端口,仅用作容器内部通信,因为它实际上是不存在的,一个实体机器上可以有很多容器,每个容器都可以有一个9999端口。所以它不能用作外部通信。
而客户端和服务端的通信是依赖于address字段的,这个字段中的端口就需要外部能够访问,所以这个端口是docker对外暴露的端口(比如这里是38890),需要另外配置好,在容器启动的时候映射到9999这个内部端口上(这个映射就不是一个通用操作了,不同的环境方法可能不一样)
之前就是没有把这两个端口区分开,所以导致客户端以9999的端口启动了,但是服务端访问不到,所以开发中还是要对整个流程有一个深刻的认知,才能够少踩坑。希望能够给你的学习工作带来一点小启发