nmap扫描端口导致线上大量Java服务FullGC甚至OOM
nmap扫描端口导致线上大量Java服务FullGC甚至OOM
最近公司遇到了一次诡异的线上FullGC保障,多个服务几乎所有的实例集中报FullGC,个别实例甚至出现了OOM,直接被docker杀掉。
观察报警服务的log,均有大量的此log
*TNonblockingServer [ERROR] Read a frame size of ****, which is bigger than the maximum allowable buffer size for ALL connections.
注意到报警的几个服务都是net in流量突然有峰值,但是对应时间的http和rpc请求数没有增加。
此时已经开始怀疑是否有人恶意的调用接口。分析log应该与rpc接口有关,rpc端口外网访问不了,请求肯定来自内网。
后查明是公司内有人在用nmap扫描端口,nmap会向端口发送随机的数据包。公司内的JavaRpc采用的是Thrift,Thrift在解析异常数据包时有概率会申请大量内存,进而导致服务OOM。
分析了一波Thrift的源码,主要关注AbstractNonblockingServer类,以及其中的FrameBuffer。这两个类主要与Thrift解析数据流有关。
thrift采用NIO进行网络数据处理,NIO将数据放到buffer中,thrift再通过socketChannel读取buffer
thrift先从socketChannel中读取4个字节数据,4个字节转成int frameSize ,thrift就认作这个frameSize是整个数据包的size了,下一步就去申请对应大小的内存,再做进一步读取。
问题就出在了这里,如果是符合thrift IDL的数据包应该就没有问题,可是nmap发送的tcp包里的数据是随机的,而且我测试发现nmap一下会发几十个tcp请求过来。
thrift估计是为了避免这个问题,在拿到frameSize后,申请内存前,会有一个判断,当frameSize > MAX_READ_BUFFER_BYTES时,会把请求认作异常,不再进行处理。
if (frameSize > MAX_READ_BUFFER_BYTES) {
LOGGER.error("Read a frame size of " + frameSize
+ ", which is bigger than the maximum allowable buffer size for ALL connections.");
return false;
}
MAX_READ_BUFFER_BYTES默认是Long.MAX_VALUE,可以在thrift的TThreadedSelectorServer构造函数中进行指定,公司指定的值为100M。
这个100M仍然过大了,当frameSize小于100M,thrift仍然会申请内存的,而nmap会几秒钟发几十个请求过来,极端情况下这几十个请求均会申请<=100M的内存,最终导致服务的OOM
一个治标不治本的解决方法是调小MAX_READ_BUFFER_BYTES。然而将MAX_READ_BUFFER_BYTES调整的过小的话也要考虑是否影响到正常的RPC请求。
总之,考虑到thrift如此迷惑的设计,运维应该在网络上做更多的限制可能会更好一点,首先RPC端口外网禁止访问,避免心怀不轨的人来搞破坏,其次内网也应该建立规范,比如扫描时尽量有意的避开绕过RPC端口。
核心代码
public boolean read() {
if (state_ == FrameBufferState.READING_FRAME_SIZE) {
// try to read the frame size completely
if (!internalRead()) {
return false;
}
// if the frame size has been read completely, then prepare to read the
// actual frame.
if (buffer_.remaining() == 0) {
// pull out the frame size as an integer.
int frameSize = buffer_.getInt(0);
if (frameSize <= 0) {
LOGGER.error("Read an invalid frame size of " + frameSize
+ ". Are you using TFramedTransport on the client side?");
return false;
}
// if this frame will always be too large for this server, log the
// error and close the connection.
if (frameSize > MAX_READ_BUFFER_BYTES) {
LOGGER.error("Read a frame size of " + frameSize
+ ", which is bigger than the maximum allowable buffer size for ALL connections.");
return false;
}
// if this frame will push us over the memory limit, then return.
// with luck, more memory will free up the next time around.
if (readBufferBytesAllocated.get() + frameSize > MAX_READ_BUFFER_BYTES) {
return true;
}
// increment the amount of memory allocated to read buffers
readBufferBytesAllocated.addAndGet(frameSize + 4);
// reallocate the readbuffer as a frame-sized buffer
buffer_ = ByteBuffer.allocate(frameSize + 4);
buffer_.putInt(frameSize);
state_ = FrameBufferState.READING_FRAME;
} else {
// this skips the check of READING_FRAME state below, since we can't
// possibly go on to that state if there's data left to be read at
// this one.
return true;
}
}
// it is possible to fall through from the READING_FRAME_SIZE section
// to READING_FRAME if there's already some frame data available once
// READING_FRAME_SIZE is complete.
if (state_ == FrameBufferState.READING_FRAME) {
if (!internalRead()) {
return false;
}
// since we're already in the select loop here for sure, we can just
// modify our selection key directly.
if (buffer_.remaining() == 0) {
// get rid of the read select interests
selectionKey_.interestOps(0);
state_ = FrameBufferState.READ_FRAME_COMPLETE;
}
return true;
}
// if we fall through to this point, then the state must be invalid.
LOGGER.error("Read was called but state is invalid (" + state_ + ")");
return false;
}
参考:https://my.oschina.net/shipley/blog/422204
nmap扫描端口导致线上大量Java服务FullGC甚至OOM的更多相关文章
- 一次性搞清楚线上CPU100%,频繁FullGC排查套路
“ 处理过线上问题的同学基本上都会遇到系统突然运行缓慢,CPU 100%,以及 Full GC 次数过多的问题. 当然,这些问题最终导致的直观现象就是系统运行缓慢,并且有大量的报警. 本文主要针对系统 ...
- Java服务,内存OOM问题如何快速定位? (转)
转自:公众号 架构师之路 问题:有一个Java服务出现了OOM(Out Of Memory)问题,定位了好久不得其法,请问有什么好的思路么? OOM的问题,印象中之前写过,这里再总结一些相对通用的方 ...
- 关于GC(上):Apache的POI组件导致线上频繁FullGC问题排查及处理全过程
某线上应用在进行查询结果导出Excel时,大概率出现持续的FullGC.解决这个问题时,记录了一下整个的流程,也可以作为一般性的FullGC问题排查指导. 1. 生成dump文件 为了定位FullGC ...
- 关于nmap扫描端口
nmap查看一个服务器的端口,是通过扫描来实现的.所以在本机执行nmap扫描的端口有可能被防火墙阻止,在外部是访问不了的. 如:开启ORACLE监听后,在本机使用nmap 127.0.0.1是可以扫描 ...
- 案例分享 | dubbo 2.7.12 bug导致线上故障
本文已收录 https://github.com/lkxiaolou/lkxiaolou 欢迎star.搜索关注微信公众号"捉虫大师",后端技术分享,架构设计.性能优化.源码阅读. ...
- 【Maven篇】---解决Maven线上部署java.lang.ClassNotFoundException和no main manifest attribute解决方法
一.前述 maven 线上部署的话会出现一些问题比如java.lang.ClassNotFoundException或者no main manifest attribute的话,是因为maven 配置 ...
- 记一次log4j日志导致线上OOM问题案例
最近一个服务突然出现 OutOfMemoryError,两台服务因为这个原因挂掉了,一直在full gc.还因为这个问题我们小组吃了一个线上故障.很是纳闷,一直运行的好好的,怎么突然就不行了呢... ...
- CentOS上部署JAVA服务【转】
http://www.th7.cn/Program/java/201511/686437.shtml 本文将介绍如何在CentOS上运行Java Web服务,其中将包括如何搭建JAVA运行环境.如何开 ...
- nmap 扫描端口 + iftop 实时监控流量
sleep 1|telnet 127.0.0.1 223 nmap 127.0.0.1 -p 223 -PN (对禁ping IP) iftop -P -n -B -B 按字节显示 -N 切换 端 ...
随机推荐
- Day01_03_Java名词
java名词 SDK 软件开发工具包 JDK Java的软件开发工具包,其中包括Java虚拟机(JVM),Java运行环境(即jre),Java工具(编译器,运行工具等)和Java基础类库等. JRE ...
- 测试工具PerfDog的使用
使用操作:https://www.jianshu.com/p/cc04c710e643下载地址:https://perfdog.qq.com/
- HIT手 | 机械电气构造简述和微分运动学及静力学的简单推导
机械结构电气构造简述 HIT手有四个手指,每个手指4个关节,其中第一和第二个关节正交,第三和第四个关节机械耦合,故只有3个自由度,另外大拇指多了一个相对手掌运动的自由度,故一只手掌总共有13各个自 ...
- 关于Number、parseInt、isNaN转化参数
1.首先,关于NaN的相等判断 alert(NaN==NaN) //返回的是false: 2.isNaN 确定这个参数是否是数值或者是否可以被转化为数值:NaN是not a number 的缩写,所以 ...
- hdu3313 最大流找关键点,或者最短路找关键点.
题意: 给你一个有向图,然后给你起点和终点,问你从起点到终点有多少个关键点,如果当前的这个点删除了就无法从起点到终点,那么这个点就是一个关键点.. 思路: (1)有两种做法,我用的 ...
- LA3213加密
题意: 白书上有些题的题意说的太蛋疼了,这个题的意思是说有两种加密方式,一种是交换位置,另一种是一一映射,交换位置是指如ABCD 可以加密成DCBA 也可以加密成ACBD就是把某些字母的位 ...
- Linux下性能监控、守护进程与计划任务管理
目录 一:监视系统进程(ps .top) 二:查看网络连接信息 (netstat) 三:文件进程.端口关联(lsof) 四:计划任务管理(at .crontab) at crontab 一:监视系统进 ...
- 学习Canvas绘图与动画基础 绘制多条路径(四)
1 <!DOCTYPE html> 2 <html> 3 <head lang="en"> 4 <meta charset="U ...
- 【JavaScript】【KMP】Leetcode每日一题-实现strStr()
[JavaScript]Leetcode每日一题-实现strStr() [题目描述] 实现 strStr() 函数. 给你两个字符串 haystack 和 needle ,请你在 haystack 字 ...
- IOS Widget(5):小组件刷新机制
引言 前面的章节学完已经让我们可以顺利实现一个小组件了,但是小组件里面的数据如何刷新的呢,本节内容将讲解IOS的刷新机制. 大纲 系统如何管理小组件刷新 Timeline刷新机制 Timeline ...