文档章节

当 Thrift 遇到 JDK Epoll Bug

輕風
 輕風
发布于 2017/08/12 17:04
字数 901
阅读 2049
收藏 110
点赞 6
评论 25

##前言 相信不少 Java server 端程序深受臭名昭著的 JDK Epoll Bug 其害。一旦触发所有 Selector 线程处于空转状态不能自拔,直至 cpu 跑满,不再处理外来连接。对于外部调用者来说这意味着服务不可用,这真是一场灾难。

笔者不才,前段时间在使用 Thrift 作为 server 端 rpc 框架对外提供服务时刚好触发了此 bug ,在此记录定位问题的过程和解决办法,供各位参考,望再有后来人碰到此问题不在受此困扰。话不多说,先来复盘。

问题定位

话说服务端程序都已开心码完,在做最后的压测时,突然发现压测程序请求不到服务直至访问超时。赶紧到所在服务器查看服务状况,结果发现多个 cpu 跑满了,如下图:

cpu run full

于是赶紧用 top -Hp $PID 查看下所在进程的线程情况,结果如下图:

thread info in progress

按 cpu 使用量排序后,发现前面几个线程 cpu 使用量接近 100% 。 Java 程序快用 jstack 查看这个线程在干嘛吧,定位到 pid=177 ( 0xb1 ) 的线程堆栈信息如下:

thread details

从堆栈信息可以看到触发点位于 Thrift 的 TThreadedSelectorServer.select() 方法中,查看源码可知其不过是调用了JDK Selector.select() 方法。(注:为描述方便笔者把实例方法调用使用类方法调用形式展示)

TThreadedSelectorServer.select()

看现象初步认为是压测时连接数过多导致 Selector 线程一直处于繁忙状态,可后来发现停掉压测 cpu 使用量还是居高不下。

笔者曾一度陷入困境,后经高人同事提点道:会不会是JDK Epoll Bug ?我一想这个 bug 官方不是修复了吗,后来查证发现:官方声称在JDK1.6版本的update18修复了该问题,然而只是降低了发生的概率而已,它并没有被根本解决。该 bug 以及相关的问题如下:

http://bugs.java.com/bugdatabase/view_bug.do?bug_id=6403933

http://bugs.java.com/bugdatabase/view_bug.do?bug_id=2147719

笔者当时环境为:

work JRE

看来到 jdk 1.8 这个问题也没解决,为 Oracle 感到小小的尴尬啊。

解决办法

JDK 的 bug 让使用者极其的尴尬啊,因为我们又不能更改其源码。好在好的搜索引擎拉低了学习的门槛,在茫茫互联网中帮我找到了一位高人总结的解决办法,其中有详细写明触发原因及解决办法,详见:

应用服务器中对JDK的epoll空转bug的处理

笔者简述下解决办法:

  1. 确认程序触发 epoll bug :在一定时间间隔内触发了设定阈值次数的空转,则认定触发 epoll bug
  2. 修复:通过重建 Selector 方式,新 Selector 注册问题 Selector 所有事件后替换它。

定位到问题及知道解决办法后,接下来就赶紧修复它吧。

按照 Thrift 官方 Developers 贡献指南一步步来:

至此问题修复完成。感兴趣者可以关注上述 issue 来获取官方修复的最新进展。

参考博客:

应用服务器中对JDK的epoll空转bug的处理

Java NIO通信框架在电信领域的实践

转载此博客请注明来源:https://my.oschina.net/johnnyliao/blog/1507141

© 著作权归作者所有

共有 人打赏支持
輕風
粉丝 4
博文 2
码字总数 1601
作品 0
朝阳
程序员
加载中

评论(25)

j4love
j4love
我用 jdk 1.8 在 windows 环境下也发现这个问题了 , 刚开始还怀疑是不是这个原因导致的 , 尝试了 netty 的解决方法后立马见效了
輕風
輕風

引用来自“xiaoxin”的评论

最近我们的应用也发现了此bug,我们用的WEBLOGIC 10.3.6.0,使用的netty,通过jstack抓日志,发现是netty的问题,但这个发生WEBLOGIC调用的问题,楼主,weblogic的遇到的这个问题如何解决呢?我目前没找到是哪个jar用到的。Oracle官网也没有找到类似的问题。
netty新版本中是修复了此问题的,确认是netty问题可以通过升级修复
xiaoxin
xiaoxin
最近我们的应用也发现了此bug,我们用的WEBLOGIC 10.3.6.0,使用的netty,通过jstack抓日志,发现是netty的问题,但这个发生WEBLOGIC调用的问题,楼主,weblogic的遇到的这个问题如何解决呢?我目前没找到是哪个jar用到的。Oracle官网也没有找到类似的问题。
輕風
輕風

引用来自“ghmasiol”的评论

最近发现facebook有个Nifty,是使用Thrift+Netty3的,博主用过吗?如果用过的话能分享下经验吗?
没用过,如果你需要使用的话,期待你之后的分享
g
ghmasiol
最近发现facebook有个Nifty,是使用Thrift+Netty3的,博主用过吗?如果用过的话能分享下经验吗?
orpherus
orpherus

引用来自“輕風”的评论

引用来自“orpherus”的评论

去oracle报jdk bug吧
准备去,然而这么多年来官方给出的办法也就是重建 Selector(JDK-6403933),所以最快的办法还是在框架中屏蔽。

jdk团队认为只有2.4内核有这个问题,而且他们认为已经修复了,这个issue值得关注
輕風
輕風

引用来自“orpherus”的评论

去oracle报jdk bug吧
准备去,然而这么多年来官方给出的办法也就是重建 Selector(JDK-6403933),所以最快的办法还是在框架中屏蔽。
orpherus
orpherus
去oracle报jdk bug吧
Raphael_goh
Raphael_goh

引用来自“Raphael_goh”的评论

官方说这是linux2.4的bug,而且不打算合并你的pr:joy::joy::joy:

引用来自“Raynor1”的评论

我觉得楼主搞错了一个地方就是在压力大的时候。其实是可以有Cpu 100%的。。说明是处理事件呀。。而oracle 的那个bug是说。当触发了这一个事件后。他的cpu 100%怎么样都下不了的问题(无法再解放),所以造成楼主这一个问题应该是逻辑处理慢造成所并不是上面的这一个地方的处理造成的哈。

引用来自“輕風”的评论

可能没表诉清楚,后面说了停掉压测后无外来连接时cpu还是跑满状态的
这问题我也遇到过,我们的日志库发送日志到kafka的时候参数没有调整好,压测2分钟后,tps就降到1/10甚至到0,几乎不响应请求(此时停止压测可以恢复),再持续压测几分钟后,就完全无法恢复了。调整kafka Client的buffer大小或改小kafka的timeout时间可以解决这个问题。
輕風
輕風

引用来自“FPE”的评论

厉害了,java把epoll弄得像select一样。文章所说的“连接数过多导致 Selector 线程一直处于繁忙状态”,这绝对是select模型,一定是用select实现了一个假epoll,哈哈哈。我用epoll(c++)测试接受连接(还是用虚拟机测试),不到5秒就能接受50000个新连接。所以你是平均每秒有10000个连接请求导致一直卡顿吗?
java 的 Selector(选择器)有多种实现方式,实现了 poll epoll 等多种模型。无业务情况下测过qps 轻松上 10w 的,性能是没问题的,主要是触发了 jdk 的 bug 导致其处于空转状态而不能处理外来连接。
netty替代原生的nio原因?

JAVA NIO相对于Old IO APIs 有非常大的改进,但是使用NIO是受限制的。有些是设计问题,有些是缺陷导致,而netty已经解决了这些问题。 ①跨平台与兼容性 NIO算是底层的APIs需依赖奥佐系统的I...

磨砂轮
2016/09/20
407
0
JAVA NIO存在的问题

JAVA 包含最新的版本JDK1.8的NIO存在一些问题,这些问题需要在编写NIO程序时要格外关注: NIO跨平台和兼容性问题 NIO是底层API,它的实现依赖于操作系统针对IO操作的APIs. 所以JAVA能在所有操...

cloud-coder
2016/05/04
782
1
Apache Thrift 官方 java教程

Apache Thrift 维基百科 Thrift是一种接口描述语言和二进制通讯协议,它被用来定义和创建跨语言的服务。它被当作一个远程过程调用(RPC)框架来使用,是由Facebook为“大规模跨语言服务开发”...

___k先生
2017/11/28
0
0
Apache Flume 1.3.1 发布,日志服务器

Flume 是一个分布式、可靠和高可用的服务,用于收集、聚合以及移动大量日志数据,使用一个简单灵活的架构,就流数据模型。这是一个可靠、容错的服务。 Apache Flume 1.3.1 发布了,详细改进内...

oschina
2013/01/04
2.1K
1
如何为分布式系统优雅的更换RPC

为啥需要更换RPC? 很多小伙伴都遇到过需要为分布式系统调用更换RPC的问题,为什么会遇到这种事呢?其实,在系统搭建初期,需求简单,架构简单,最重要的是请求量也少,所以很多系统都采用快速...

Java团长17
07/11
0
0
编译hbase1.2.6源码并安装环境

1.下载安装包 先从官网上下载当前最新的稳定版源码包 https://mirrors.tuna.tsinghua.edu.cn/apache/hbase/stable/hbase-1.2.6-src.tar.gz 2.编译 解压之后执行命令 mvn cleanpackage -Dski...

土木匠
2017/12/10
0
0
hy0kl/event-json-rpc

event-json-rpc 基于 libevent,以二进制头+json为协议来实现的 rpc 框架. 参考和依赖 libeventcJSONzloglibzdb 以此为基础 https://github.com/jasonish/libevent-examples json c 解析器 ht......

hy0kl
2017/09/03
0
0
Netty 4.0.25.Final 发布,高性能网络应用框架

Netty 4.0.25.Final 在 2014 年结束之前发布了,该版本修复了超过 20 个 bug,同时包含如下新特性和改进: SSL Works as a drop-in replacement of JDK stock ! adds ALPN and mutual authe...

oschina
2015/01/01
3.6K
5
thrift-generator 0.1 发布,通过 Java 接口生成 Thrift 文件工具

这是一个通过java的接口生成thrift文件的工具, 这个代码库的时间悠久, 已经有5年历史了, 当时写这个工具主要两个目的: 没接触thrift,但是希望使用thrift的用户,可以便于新用户的理解 之前用的...

hongliuliao
2017/12/11
649
3
python操作hbase 远程连接

欢迎访问我的个人博客 目的 用python操作hbase。 这里是在linux上搭建的是一个测试环境,所以hbase是单机版本安装,安装thrift是为了支持python操作hbase。 网上也有类似教程,但是坑也不少,...

TENLIU2099
2017/10/19
0
0

没有更多内容

加载失败,请刷新页面

加载更多

下一页

大数据教程(2.13):keepalived+nginx(多主多活)高可用集群搭建教程【自动化脚本】

上一章节博主为大家介绍了目前大型互联网项目的keepalived+nginx(主备)高可用系统架构体系,相信大家应该看了博主的文章对keepalived/nginx技术已经有一定的了解,在本节博主将为大家分享k...

em_aaron
3分钟前
0
0
Git 2.18版本发布:支持Git协议v2,提升性能

在最新的官方 Git 客户端正式版2.18中添加了对 Git wire 协议 v2 的支持,并引入了一些性能与 UI 改进的新特性。在 Git 的核心团队成员 Brandon Williams 公开宣布这一消息前几周,Git 协议 ...

六库科技
8分钟前
0
0
Java8新特性之接口

在JDK8以前,我们定义接口类中,方法都是抽象的,并且不能存在静态方法。所有的方法命名规则基本上都是 public [返回类型] [方法名](参数params) throws [异常类型] {}。 JDK8为接口的定义带...

developlee的潇洒人生
46分钟前
0
0
aop + annotation 实现统一日志记录

aop + annotation 实现统一日志记录 在开发中,我们可能需要记录异常日志。由于异常比较分散,每个 service 方法都可能发生异常,如果我们都去做处理,会出现很多重复编码,也不好维护。这种...

长安一梦
57分钟前
2
0
将博客搬至CSDN

AHUSKY
今天
1
0
Python web框架Django学习(1)

1.Django简介 (1)Python下有许多款不同的 Web 框架。Django是重量级选手中最有代表性的一位。许多成功的网站和APP都基于Django。Django是一个开放源代码的Web应用框架,由Python写成。 (2...

十年磨一剑3344
今天
0
0
Databook-数据之书

Databook-数据之书 用于数据分析的Jupyter Notebooks。 不需购买服务器,快速开始自己的数据分析过程。 源码:https://github.com/openthings/databook 作者:openthings,https://github.co...

openthings
今天
5
0
Python PIPEs

https://www.python-course.eu/pipes.php https://www.tutorialspoint.com/python/os_pipe.htm

zungyiu
今天
1
0
gRPC学习笔记

gRPC编程流程 1. proto文件定义 proto文件用于定义需要通过gRPC生成的接口,可以理解为接口定义文档 2. 通过构建工具生成服务基类代码-Maven或Gradle 3. 服务端开发 服务端实现类须实现通过构...

OSC_fly
今天
0
0
Docker Mac (三) Dockerfile 及命令

Dockerfile 最近学习docker的时候,遇到一件怪事,关于docker镜像可能会被破坏,还不知道它会有此措施 所以需要了解构建Dockerfile的正确方法 Dockerfile是由一系列命令和参数构成的脚本,这些命...

___大侠
今天
0
0

没有更多内容

加载失败,请刷新页面

加载更多

下一页

返回顶部
顶部