文章目录
- 1. 问题呈现
- 2. 问题产生的原因
- 2.1 原因一:执行器和调度中心部署在不同的机器上
- 2.2 原因二:调度中心部署在云服务器上
- 3. 解决方法
- 3.1 方法一:将执行器和调度中心部署在同一台机器上
- 3.2 方法二:手动指定执行器的ip地址(执行器和调度中心需要在同一网络环境下)
- 3.3 方法三:内网穿透(通用方法)
- 3.3.1 创建隧道
- 3.3.2 获取公网地址
- 3.3.3 设置执行器的地址
阅读本文前可以先阅读以下文章:
- XXL-JOB快速入门(什么是XXL-JOB、部署XXL-JOB、在SpringBoot项目中接入XXL-JOB、XXL-JOB中的核心概念、集群环境下任务的路由策略)
1. 问题呈现
在调度中心查看调度日志
任务执行失败的原因如下
任务触发类型:Cron触发
调度机器:172.17.0.4
执行器-注册方式:自动注册
执行器-地址列表:[http://localhost:11015/, http://localhost:11016/]
路由策略:轮询
阻塞处理策略:单机串行
任务超时时间:0
失败重试次数:0
>>>>>>>>>>>触发调度<<<<<<<<<<<
触发调度:
address:http://localhost:11016/
code:500
msg:xxl-job remoting error(Connection refused (Connection refused)), for url : http://localhost:11016/run
如果你是通过 docker 部署 XXL-JOB 的调度中心的,通过 docker 的日志也能查看到错误信息
sudo docker ps --format '{{.Names}}'
sudo docker logs --tail xxl-job-admin
ubuntu@VM-0-5-ubuntu:~$ sudo docker logs --tail 30 xxl-job-admin
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
at java.lang.Thread.run(Thread.java:750)
02:46:47.714 logback [xxl-job, admin JobTriggerPoolHelper-slowTriggerPool-1343446290] ERROR c.x.job.core.util.XxlJobRemotingUtil - Connection refused (Connection refused)
java.net.ConnectException: Connection refused (Connection refused)
at java.net.PlainSocketImpl.socketConnect(Native Method)
at java.net.AbstractPlainSocketImpl.doConnect(AbstractPlainSocketImpl.java:350)
at java.net.AbstractPlainSocketImpl.connectToAddress(AbstractPlainSocketImpl.java:206)
at java.net.AbstractPlainSocketImpl.connect(AbstractPlainSocketImpl.java:188)
at java.net.SocksSocketImpl.connect(SocksSocketImpl.java:392)
at java.net.Socket.connect(Socket.java:607)
at sun.net.NetworkClient.doConnect(NetworkClient.java:175)
at sun.net.www.http.HttpClient.openServer(HttpClient.java:463)
at sun.net.www.http.HttpClient.openServer(HttpClient.java:558)
at sun.net.www.http.HttpClient.(HttpClient.java:242)
at sun.net.www.http.HttpClient.New(HttpClient.java:339)
at sun.net.www.http.HttpClient.New(HttpClient.java:357)
at sun.net.www.protocol.http.HttpURLConnection.getNewHttpClient(HttpURLConnection.java:1228)
at sun.net.www.protocol.http.HttpURLConnection.plainConnect0(HttpURLConnection.java:1162)
at sun.net.www.protocol.http.HttpURLConnection.plainConnect(HttpURLConnection.java:1056)
at sun.net.www.protocol.http.HttpURLConnection.connect(HttpURLConnection.java:990)
at com.xxl.job.core.util.XxlJobRemotingUtil.postBody(XxlJobRemotingUtil.java:99)
at com.xxl.job.core.biz.client.ExecutorBizClient.run(ExecutorBizClient.java:43)
at com.xxl.job.admin.core.trigger.XxlJobTrigger.runExecutor(XxlJobTrigger.java:211)
at com.xxl.job.admin.core.trigger.XxlJobTrigger.processTrigger(XxlJobTrigger.java:164)
at com.xxl.job.admin.core.trigger.XxlJobTrigger.trigger(XxlJobTrigger.java:89)
at com.xxl.job.admin.core.thread.JobTriggerPoolHelper
3.
r
u
n
(
J
o
b
T
r
i
g
g
e
r
P
o
o
l
H
e
l
p
e
r
.
j
a
v
a
:
95
)
a
t
j
a
v
a
.
u
t
i
l
.
c
o
n
c
u
r
r
e
n
t
.
T
h
r
e
a
d
P
o
o
l
E
x
e
c
u
t
o
r
.
r
u
n
W
o
r
k
e
r
(
T
h
r
e
a
d
P
o
o
l
E
x
e
c
u
t
o
r
.
j
a
v
a
:
1149
)
a
t
j
a
v
a
.
u
t
i
l
.
c
o
n
c
u
r
r
e
n
t
.
T
h
r
e
a
d
P
o
o
l
E
x
e
c
u
t
o
r
3.run(JobTriggerPoolHelper.java:95) at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149) at java.util.concurrent.ThreadPoolExecutor
3.run(JobTriggerPoolHelper.java:95)atjava.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149)atjava.util.concurrent.ThreadPoolExecutorWorker.run(ThreadPoolExecutor.java:624)
at java.lang.Thread.run(Thread.java:750)
2. 问题产生的原因
2.1 原因一:执行器和调度中心部署在不同的机器上
在 XXL-JOB 中,执行器(Executor)是指那些实际执行任务的远程服务。每个执行器都会向 XXL-JOB 的调度中心(Admin)注册自己,并定期发送心跳以保持其注册状态。
如果执行器启动时填写的 ip 地址为 localhost,但执行器和调度中心部署在不同的机器上,那么 XXL-JOB 调度中心将会找不到执行器
执行器的相关信息会被记录在 xxl_job
数据库的 xxl_job_registry
表中
因为 localhost 代表的是本地,对于调度中心来说,localhost 就是部署调度中心的机器,因为执行器和调度中心部署在不同的机器上,调度中心肯定找不到执行器
2.2 原因二:调度中心部署在云服务器上
如果你是通过云服务器来部署调度中心,但执行器却是在局域网中运行的,那么调度中心将无法与执行器建立连接
Windows环境下使用ipconfig
命令显示的IP地址通常是局域网(Local Area Network, LAN)的IP地址。这个地址是根据计算机在局域网中的位置由网络中的DHCP服务器(通常是路由器)分配的,这个地址一般是私有地址,范围如下:
- 10.0.0.0 到 10.255.255.255
- 172.16.0.0 到 172.31.255.255
- 192.168.0.0 到 192.168.255.255
这些私有地址是不会直接在互联网上路由的,它们仅供局域网内部使用。如果计算机需要访问互联网,那么它会通过网络地址转换(NAT)使用一个公网IP地址来与互联网上的其他设备通信。公网IP地址是由您的互联网服务提供商(ISP)分配的,通常不会在ipconfig
命令的输出中直接显示。
3. 解决方法
3.1 方法一:将执行器和调度中心部署在同一台机器上
将执行器和调度中心部署在同一台机器上后,调度中心就能找到执行器了
3.2 方法二:手动指定执行器的ip地址(执行器和调度中心需要在同一网络环境下)
如果你是通过虚拟机(使用 VMware 等软件)部署调度中心的,可以通过手动指定执行器的 ip 地址来解决
按下 Win + R
打开命令行窗口,输入以下指令查看执行器的 ip 地址
ipconfig
圈出来的几个地址都可以试一下(优先尝试 VMnet8)
也可以在调度中心手动录入执行器(多个机器地址之间用英文逗号隔开)
3.3 方法三:内网穿透(通用方法)
如果你的调度中心是部署在云服务上的,那么前面两个方法都不适用,只能通过内网穿透来解决
我们使用 cpolar 实现内网穿透,cpolar 的使用教程可以参考我的另一篇博文:使用cpolar实现内网穿透,将Web项目部署到公网上
3.3.1 创建隧道
在浏览器打开 cpolar 的控制台,创建隧道
http://localhost:9200/#/tunnels/create
- 自定义隧道名称
- 本地地址与执行器占用的端口保持一致
3.3.2 获取公网地址
查看在线隧道列表,将公网地址记录下来(电脑重启后生成的公网地址可能会发生变化)
3.3.3 设置执行器的地址
可以在执行器中设置执行器的地址(无需再设置 ip 地址)
也可以在调度中心手动录入执行器(多个机器地址之间用英文逗号隔开)