关于XXLJOB集群模式下调度失败的问题
xxljob在集群模式下调度高频任务时,有时会出现调度失败的问题,具体报错如下:
java.io.EOFException: HttpConnectionOverHTTP@6be8bf0c(l:/10.48.2.64:38538 <-> r:/10.48.1.125:18989,closed=false)[HttpChannelOverHTTP@296ee40c(exchange=HttpExchange@4d219770 req=TERMINATED/null@null res=PENDING/null@null)[send=HttpSenderOverHTTP@3c6b8ccf(req=QUEUED,snd=COMPLETED,failure=null)[HttpGenerator{s=START}],recv=HttpReceiverOverHTTP@12554491(rsp=IDLE,failure=null)[HttpParser{s=CLOSED,0 of -1}]]]
at org.eclipse.jetty.client.http.HttpReceiverOverHTTP.earlyEOF(HttpReceiverOverHTTP.java:277)
at org.eclipse.jetty.http.HttpParser.parseNext(HttpParser.java:1305)
at org.eclipse.jetty.client.http.HttpReceiverOverHTTP.shutdown(HttpReceiverOverHTTP.java:182)
at org.eclipse.jetty.client.http.HttpReceiverOverHTTP.process(HttpReceiverOverHTTP.java:129)
at org.eclipse.jetty.client.http.HttpReceiverOverHTTP.receive(HttpReceiverOverHTTP.java:69)
at org.eclipse.jetty.client.http.HttpChannelOverHTTP.receive(HttpChannelOverHTTP.java:90)
at org.eclipse.jetty.client.http.HttpConnectionOverHTTP.onFillable(HttpConnectionOverHTTP.java:174)
at org.eclipse.jetty.io.AbstractConnection$2.run(AbstractConnection.java:544)
at org.eclipse.jetty.util.thread.QueuedThreadPool.runJob(QueuedThreadPool.java:635)
at org.eclipse.jetty.util.thread.QueuedThreadPool$3.run(QueuedThreadPool.java:555)
at java.lang.Thread.run(Thread.java:748)
网上关于这个问题的原因和解决比较少,因此记录下来问题的排查过程,供大家参考,如果有心急的同学可以直接跳到结尾查看问题原因和解决方案
后续说明中的触发侧是指xxljob的服务端,执行侧是指任务执行的应用端
排查过程中需要对xxljob的执行原理有大概的了解,以及tcp的握手和挥手操作有一定的了解,最后还需要知道一些tcpdump命令结果的一些知识,如果有不明白的可以先查一下相关资料
首先,我看到这个问题之后先去网上搜一下有没有问题的原因说明和解决方案,但是查询之后发现虽然很多人都遇到了,但是没有说明具体的问题原因
所以,只好查看一下xxl的源码,发现触发操作是完全隔离的,集群下不同机器没有任何相互影响。而且非集群模式下没有这个问题,说明可以排除网络因素。
同时,我也将xxljob中发起触发请求的代码复制出来,然后进行高频率调用,但是没有复现出问题,说明问题的出现可能跟高频执行没有太大关系
肯定是不同机器调度过程中导致的,仔细观察下图中的调度记录,可以看到出问题的时间点总是在切换调度机器的第一次请求时发生。但是调度机器触发操作是完全独立的,所以到这里就不明白为什么会出现这种情况
于是,为了进一步排查问题,只能去尝试抓一下网络请求,看网络请求有什么不同

下面这个图是通过tcpdump命令抓取的任务触发机器和任务执行机器的网络通信过程
看到这个我才发现,虽然xxljob是使用http进行通信的,但是并不是走的短连接,而是长连接。
所以第一时间我认为是可能不同机器都已经建立了长连接但是由于调度触发一直在其中一台机器上,所以另一台的连接可能已经断开了,当触发切换到另一台机器时,由于连接已经断开,但是应用层尚未感知到,所以造成的问题
另外,从这个网络交互日志中可以看到复用长连接的有效时间是30s(这个其实是后面发现问题的关键)

根据上面分析的结果,思考问题的其他表现时,发现上面的推断并不能解释所有的现象,比如下图的表现

如果长连接已经中断,那么触发侧的请求无法发送到执行侧,执行侧的信息也无法反馈到触发侧才对。但是上面这个图中可以明显看到触发侧已经获取到了执行侧的报错信息,说明,执行侧报错之后已经通过原有连接将报错信息返回到了触发侧
这说明问题发生时,连接并没有中断,上面的分析是错误的。
之后又抓取到了问题发生时的网络交互日志,其中10.48.2.64.38538是xxljob服务端,也就是触发侧,10.48.1.125.18989是任务执行应用,也就是执行侧
16:26:46.008470 IP 10.48.2.64.38538 > 10.48.1.125.18989: Flags [P.], seq 756:1511, ack 344, win 219, length 755
16:26:46.009007 IP 10.48.1.125.18989 > 10.48.2.64.38538: Flags [F.], seq 344, ack 756, win 56, length 0
16:26:46.009192 IP 10.48.2.64.38538 > 10.48.1.125.18989: Flags [F.], seq 1511, ack 345, win 219, length 0
16:26:46.009916 IP 10.48.1.125.18989 > 10.48.2.64.38538: Flags [.], ack 1512, win 59, length 0
从上面这个日志中可以看到
第一条是触发侧去发送了一次请求到执行侧,发送的包的seq是756到1511
第二条是执行侧反馈的返回结果,执行侧直接发送了关闭连接的请求,并且ack只确认到756
第三条是触发侧确认了关闭请求,第四条执行侧确认了第三条的请求
所以2,3,4条是完整的走完了tcp的三次挥手操作,说明连接是执行侧主动关闭的
然后我们重新观察了一下正常的关闭连接的请求,发现每次都是由执行侧去关闭的连接,并且关闭的时间就是最后一次的请求的30s之后(空闲超时)
同时我们也从源码中可以看到超时时间默认就是30s

看到这里一切就都可以解释通了,由于执行侧30s超时时会断开连接,此时如果正好调度触发是从这台机器发起的,那么这次触发请求正好遇到执行侧关闭连接,执行侧发起关闭请求后,不会再接收来自触发侧的消息
所以应用由于无法读取请求的数据,所以报了eof错误
看明白报错的过程之后,我们来验证一下我们的猜想,看是否符合我们的预期
既然是30s超时会断开连接,那么如果我们的触发间隔设置为30s,那么就应该很容易碰到这种情况
因此,我将xxljob中发起触发请求的代码复制出来,然后将两次请求的间隔设置为30s,如下图:
通过下面的代码,可以很轻松的将问题复现出来,说明上面的分析是没有问题的

明白了问题所在,那么修复就比较简单了,我是采用修改空闲超时时间为10分钟,这样尽量避免调度切换和超时断开正好碰到一起
这种解决方式理论上仍然有报错的可能,但是概率大大降低了,同时也不需要修改xxljob源码,改动也比较小
如果有更好的解决方式欢迎评论区说明
测试类和修复类我都已经上传到csdn了,由于我比较贫穷,需要一些csdn的积分下载别的资源,所以希望各位支持一些积分给我
下载链接:https://download.csdn.net/download/wsss_fan/88299099
如果确实没有积分,可以联系我,我单独发给你
关于XXLJOB集群模式下调度失败的问题的更多相关文章
- Spark Streaming揭秘 Day31 集群模式下SparkStreaming日志分析(续)
Spark Streaming揭秘 Day31 集群模式下SparkStreaming日志分析(续) 今天延续昨天的内容,主要对为什么一个处理会分解成多个Job执行进行解析. 让我们跟踪下Job调用过 ...
- Spark Streaming揭秘 Day30 集群模式下SparkStreaming日志分析
Spark Streaming揭秘 Day30 集群模式下SparkStreaming日志分析 今天通过集群运行模式观察.研究和透彻的刨析SparkStreaming的日志和web监控台. Day28 ...
- 7.redis 集群模式的工作原理能说一下么?在集群模式下,redis 的 key 是如何寻址的?分布式寻址都有哪些算法?了解一致性 hash 算法吗?
作者:中华石杉 面试题 redis 集群模式的工作原理能说一下么?在集群模式下,redis 的 key 是如何寻址的?分布式寻址都有哪些算法?了解一致性 hash 算法吗? 面试官心理分析 在前几年, ...
- 就publish/subscribe功能看redis集群模式下的队列技术(一)
Redis 简介 Redis 是完全开源免费的,是一个高性能的key-value数据库. Redis 与其他 key - value 缓存产品有以下三个特点: Redis支持数据的持久化,可以将内存中 ...
- 【Redis集群原理专题】分析一下相关的Redis集群模式下的脑裂问题!
技术格言 世界上并没有完美的程序,但是我们并不因此而沮丧,因为写程序就是一个不断追求完美的过程. 什么是脑裂 字面含义 首先,脑裂从字面上理解就是脑袋裂开了,就是思想分家了,就是有了两个山头,就是有了 ...
- LB+nginx+tomcat7集群模式下的https请求重定向(redirect)后变成http的解决方案
0. 环境信息 Linux:Linux i-8emt1zr1 2.6.32-573.el6.x86_64 #1 SMP Wed Jul 1 18:23:37 EDT 2015 x86_64 x86_6 ...
- Redis集群模式下的redis-py-cluster方式读写测试
与MySQL主从复制,从节点可以分担部分读压力不一样,甚至可以增加slave或者slave的slave来分担读压力,Redis集群中的从节点,默认是不分担读请求的,从节点只作为主节点的备份,仅负责故障 ...
- Hadoop框架:集群模式下分布式环境搭建
本文源码:GitHub·点这里 || GitEE·点这里 一.基础环境配置 1.三台服务 准备三台Centos7服务,基础环境从伪分布式环境克隆过来. 133 hop01,134 hop02,136 ...
- Tomcat 集群模式下 Session 更新 Bug (redis memcached 及tomcat自已的集群)
从 excel 中导入数据入系统,我们用的是先上传文件至服务器再分析所上传的文件逐行导入. 就是执行了一循环,在当前循环位置标识一下客户端就知道执行的进度了,以前的方式 是用 session.setA ...
- 使用reids结合wcf实现集群模式下的聊天室功能
1.reids的特点 Redis数据库完全在内存中,使用磁盘仅用于持久性. 相比许多键值数据存储,Redis拥有一套较为丰富的数据类型(字符串,哈希,列表,集合,有序集合),. Redis可以将数据复 ...
随机推荐
- PTA L1-064 估值一亿的AI核心代码
PTA L1-064 估值一亿的AI核心代码 有坑!不少 题目链接 题目及分析 题目: 本题要求你实现一个稍微更值钱一点的 AI 英文问答程序,规则是: 1. 无论用户说什么,首先把对方说 ...
- 啊哈C语言案例学习笔记
Hello World #include<stdio.h> /* 技术要点: 初学者在编写程序时,经常会忘记在语句后边添加分号, */ int main() { printf(" ...
- MassTransit实现Saga模式概览
原文地址:Saga Overview 编排一系列事件的能力是一个强大的功能,而MassTransit使这成为可能. saga是由协调器管理的长期事务.saga是由事件发起的,saga编排事件,saga ...
- 烂怂if-else代码优化方案
0.问题概述 代码可读性是衡量代码质量的重要标准,可读性也是可维护性.可扩展性的保证,因为代码是连接程序员和机器的中间桥梁,要对双边友好.Quora 上有一个帖子: "What are so ...
- C++面试八股文:static和const的关键字有哪些用法?
某日二师兄参加XXX科技公司的C++工程师开发岗位第7面: 面试官:C++中,static和const的关键字有哪些用法? 二师兄:satic关键字主要用在以下三个方面:1.用在全局作用域,修饰的变量 ...
- P1585 魔法阵 题解
题意: 题目传送门 可以看做一个人手中有一些宝石,并将宝石分成两组,一组的编号为 1 至 n×m/2,二组为 n×m/2+1 至 n×m+1.当两组两个宝石编号相差为 n×m/2 为一对.现在要遍历一 ...
- 【Netty】03-进阶
三. Netty 进阶 1. 粘包与半包 1.1 粘包现象 服务端代码 public class HelloWorldServer { static final Logger log = Logger ...
- 阿里云ASK试用心得(避坑贴)
前言 常年BP阿里云的各种服务,今天却被阿里云给上了一课,这一套组合拳把我安排的明明白白,血亏50大洋,算是提前为各位大佬排坑了,预祝大家中秋快乐 目的 最近阿里云首页放出了免费试用的活动,本着不用白 ...
- 文件系统考古 3:1994 - The SGI XFS Filesystem
在 1994 年,论文<XFS 文件系统的可扩展性>发表了.自 1984 年以来,计算机的发展速度变得更快,存储容量也增加了.值得注意的是,在这个时期出现了更多配备多个 CPU 的计算机, ...
- knn和线性分类器
一.knn算法概述 knn首选是最简单的分类算法,其是有监督学习的分类算法之一. 二.knn算法过程 knn(k nearest neighbors k个最近的邻居):knn是当预测一个新的值x的时候 ...