thrift OOM 内存溢出

news2025/1/16 13:40:58

最近经常发生thrift服务半夜宕机的问题,虽然是测试环境,但是每天早上重启也很恶心。

经过很长时间的摸索,终于找到了原因。先说背景:

我们用的thrift版本是0.9.2,用做service的rpc框架,某一天开始,早上到公司发现测试环境的很多服务挂掉了,一头雾水,看内存监控,发现半夜的时候,很多服务的内存涨了一倍不止,发生了堆内存溢出(java.lang.OutOfMemoryError: Java heap space),报错如下:

2023-01-04 01:03:21.294 [Thread-5] ERROR o.a.t.server.TThreadedSelectorServer [TThreadedSelectorServer.java : 553] - run() exiting due to uncaught error
java.lang.OutOfMemoryError: Java heap space
        at java.nio.HeapByteBuffer.<init>(HeapByteBuffer.java:57) ~[na:1.8.0_212]
        at java.nio.ByteBuffer.allocate(ByteBuffer.java:335) ~[na:1.8.0_212]
        at org.apache.thrift.server.AbstractNonblockingServer$FrameBuffer.read(AbstractNonblockingServer.java:371) ~[user_service_runnable.20230103204205.981d7a5da67f15db41243178083f5842e278631d:na]
        at org.apache.thrift.server.AbstractNonblockingServer$AbstractSelectThread.handleRead(AbstractNonblockingServer.java:203) ~[user_service_runnable.20230103204205.981d7a5da67f15db41243178083f5842e278631d:na]
        at org.apache.thrift.server.TThreadedSelectorServer$SelectorThread.select(TThreadedSelectorServer.java:590) ~[user_service_runnable.20230103204205.981d7a5da67f15db41243178083f5842e278631d:na]
        at org.apache.thrift.server.TThreadedSelectorServer$SelectorThread.run(TThreadedSelectorServer.java:545) ~[user_service_runnable.20230103204205.981d7a5da67f15db41243178083f5842e278631d:na]

刚开始没有往thrift身上想,毕竟一个优秀的rpc框架,facebook出品

首先,排查思路就来到了导出内存快照,看对象的,结果,导出来的hprof文件才几百兆,远远小于内存占用的几个G,看不出有什么问题。

然后,堆内没问题,那看看堆外。加了-XX:NativeMemoryTracking=detail参数(线上环境慎用),去掉了-XX:+DisableExplicitGC,然后使用
jcmd pid VM.native_memory命令查看,发现Internal区域占用了很大空间。

一番学习(百度,谷歌)之后,这是块堆外空间,紧接着又上参数了,配置了直接内存大小限制 -XX:MaxDirectMemorySize=xM。半夜再次发生OOM,不同的是,这次是直接内存溢出(java.lang.OutOfMemoryError: Direct buffer memory),看报错发现是thrift读取请求申请直接内存导致的,报错如下:

2023-01-04 01:03:21.799 [Thread-4] ERROR o.a.t.server.TThreadedSelectorServer [TThreadedSelectorServer.java : 553] - run() exiting due to uncaught error
java.lang.OutOfMemoryError: Direct buffer memory
        at java.nio.Bits.reserveMemory(Bits.java:694) ~[na:1.8.0_212]
        at java.nio.DirectByteBuffer.<init>(DirectByteBuffer.java:123) ~[na:1.8.0_212]
        at java.nio.ByteBuffer.allocateDirect(ByteBuffer.java:311) ~[na:1.8.0_212]
        at sun.nio.ch.Util.getTemporaryDirectBuffer(Util.java:241) ~[na:1.8.0_212]
        at sun.nio.ch.IOUtil.read(IOUtil.java:195) ~[na:1.8.0_212]
        at sun.nio.ch.SocketChannelImpl.read(SocketChannelImpl.java:380) ~[na:1.8.0_212]
        at org.apache.thrift.transport.TNonblockingSocket.read(TNonblockingSocket.java:142) ~[user_service_runnable.20230103204205.981d7a5da67f15db41243178083f5842e278631d:na]
        at org.apache.thrift.server.AbstractNonblockingServer$FrameBuffer.internalRead(AbstractNonblockingServer.java:539) ~[user_service_runnable.20230103204205.981d7a5da67f15db41243178083f5842e278631d:na]
        at org.apache.thrift.server.AbstractNonblockingServer$FrameBuffer.read(AbstractNonblockingServer.java:388) ~[user_service_runnable.20230103204205.981d7a5da67f15db41243178083f5842e278631d:na]
        at org.apache.thrift.server.AbstractNonblockingServer$AbstractSelectThread.handleRead(AbstractNonblockingServer.java:203) ~[user_service_runnable.20230103204205.981d7a5da67f15db41243178083f5842e278631d:na]
        at org.apache.thrift.server.TThreadedSelectorServer$SelectorThread.select(TThreadedSelectorServer.java:590) ~[user_service_runnable.20230103204205.981d7a5da67f15db41243178083f5842e278631d:na]
        at org.apache.thrift.server.TThreadedSelectorServer$SelectorThread.run(TThreadedSelectorServer.java:545) ~[user_service_runnable.20230103204205.981d7a5da67f15db41243178083f5842e278631d:na]

终于把目光移到了thrift身上(一开始没有怀疑它),于是去搜索了thrift 内存溢出,真相大白,原来是http方式调用导致的。这篇写的不错,跟我们出现的现象一样:
https://blog.csdn.net/xmtblog/article/details/79431748?utm_source=blogxgwz8

原来http方式请求thrift服务的时候,会反序列化失败,默认读取 接收数据的前四个字节作为frameSize。因为http请求是不规范的,前四个字节一算,要申请几百M甚至1G以上,一下就搞炸了。

用http方式试了下,http://127.0.0.1:port/123, 果然OOM了。

thrift是有一个参数maxReadBufferBytes,可以控制frameSize最大值的,超过报错,好死不死,我们用的0.9.2版本,这个参数默认是Long的最大值,高达很多T,在0.12.0版本后已经修改为256M了。thrift读取数据的read方法截图如下:
源码如下:
在这里插入图片描述

于是在我们框架TThreadedSelectorServer 构造方法中加了maxReadBufferBytes = 1024 * 1024,限制1M大小。

发SNAPSHOT包,重启,再次用http方式试了下,http://127.0.0.1:port/123,没有发生OOM,发生如下报错,与上面截图里第二个红箭头对上了:

2023-01-06 02:25:06.827 [Thread-6] ERROR o.a.t.s.AbstractNonblockingServer$FrameBuffer 
[AbstractNonblockingServer.java : 356] - Read a frame size of 369295360, which is bigger than the maximum allowable buffer size for ALL connections.

至此,问题解决。

为啥会有http请求调我们这个port呢,不得而知,因为我们方便在本机debug,测试环境一些端口防火墙是放开的,一着不慎就招贼了。

其实这个问题,相信也有大佬第一次看到报错,就能正确分析,去找thrift的原因了。我还是能力不足,排查了很久,但是
Talk is cheap, just do it!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/145169.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

安全狗云原生安全产品入选《2022网络安全技术应用试点示范项目名单》

近日&#xff0c;工信部正式发布《2022网络安全技术应用试点示范项目名单》。作为国内云原生安全领导厂商&#xff0c;安全狗也凭借突出的产品能力&#xff0c;入选名单。 据悉&#xff0c;此次评选需层层通过单位申报、部门初审和推荐、专家评审、网上公示等多个环节。安全狗…

玉湖冷链黄铮洪出任广东省物流标准化技术委员会副主任

1月5日&#xff0c;广东省物流标准化技术委员会(第三届)成立大会召开&#xff0c;玉湖冷链执行董事黄铮洪出任副主任委员。 大会现场 根据2022年9月广东省市场监督管理局发布的通告&#xff0c;决定成立第三届广东省物流标准化技术委员会(以下简称「标准化委员会」)。此次大会进…

七、k8s Service详解

文章目录1 Service介绍1.1 userspace 模式1.2 iptables 模式1.3 ipvs 模式2 Service类型3 Service使用3.1 实验环境准备3.2 ClusterIP类型的Service3.3 Endpoint3.4 HeadLiness类型的Service3.5 NodePort类型的Service3.6 LoadBalancer类型的Service3.7 ExternalName类型的Serv…

树莓派3B摄像头的详细使用教程(拍照+录像+监控)

树莓派4B摄像头的详细使用教程&#xff08;拍照录像监控&#xff09; 本篇博文将介绍树莓派摄像头是如何在树莓派开发板上从安装到使用的&#xff0c;博主过程中参考了许多帖子&#xff0c;现将整理的比较全面的过程分享出来&#xff0c;供大家参考使用。 排线连接 硬件连接时…

【阶段二】Python数据分析数据可视化工具使用02篇:条形图与雷达图

本篇的思维导图: 条形图 条形图与柱形图类似,几乎可以表达相同多的数据信息。条形图的柱形变为横向,从而导致与柱形图相比,条形图更加强调项目之间的大小对比。尤其在项目名称较长以及数量较多时,采用条形图可视化数据会更加美观、清晰。 代码 # 导入需要的包imp…

java学习day70(乐友商城)授权中心

1.无状态登录原理 1.1.什么是有状态&#xff1f; 有状态服务&#xff0c;即服务端需要记录每次会话的客户端信息&#xff0c;从而识别客户端身份&#xff0c;根据用户身份进行请求的处理&#xff0c;典型的设计如tomcat中的session。 例如登录&#xff1a;用户登录后&#x…

cubeIDE开发, stm32的C库应用分析

一、stm32的C库 cubeIDE针对STM32芯片开发&#xff0c;提供个了两大库&#xff0c;HLA库和C库&#xff08;集成GNU Tools for STM32工具链时提供&#xff0c;该工具链同样是意法半导体提供&#xff0c;可在http:// www.st.com单独下载&#xff09;&#xff0c;前者帮助开发这简…

P1055 [NOIP2008 普及组] ISBN 号码————C++

文章目录题目[\[NOIP2008 普及组\] ISBN 号码](https://www.luogu.com.cn/problem/P1055)题目描述输入格式输出格式样例 #1样例输入 #1样例输出 #1样例 #2样例输入 #2样例输出 #2提示解题思路1Code运行结果解题思路2Code运行结果题目 [NOIP2008 普及组] ISBN 号码 题目描述 …

windows 安装jenkins运行发布vue项目到linux服务器

文章目录背景安装jenkins安装插件安装nodej插件Publish over SSH系统配置Publish over SSH全局工具配置设置node构建项目创建一个freestyle的项目Discard old buildsgit命令报错Host key verification failedBuild背景 由于服务器上运行jenkins很卡&#xff0c;所以对于小公司…

windows安装jenkins运行发布java springboot项目到linux服务器

文章目录背景安装jenkins安装插件安装maven插件Publish over SSH系统配置Global propertiesPublish over SSH全局工具配置设置jdk设置maven设置git构建java maven项目freestyle 或者maven都可以Discard old buildsgit命令报错Host key verification failed每次构建前清理构建环…

可观测性之Log4j2优雅日志打印

可观测性之Log4j2优雅日志打印# 简介 对于Log4j2大家应该都不是很陌生&#xff0c;听说最多的应该是2021年年底出现的安全漏洞了&#xff0c;不过最让大家头痛的应该不仅仅是这个安全漏洞的处理&#xff0c;安全漏洞通过升级最新的依赖版本即可快速解决&#xff0c;平时在使用…

基于Java+SpringMvc+vue+element实现上海汽车博物馆平台

基于JavaSpringMvcvueelement实现上海汽车博物馆平台 博主介绍&#xff1a;5年java开发经验&#xff0c;专注Java开发、定制、远程、文档编写指导等,csdn特邀作者、专注于Java技术领域 作者主页 超级帅帅吴 Java毕设项目精品实战案例《500套》 欢迎点赞 收藏 ⭐留言 文末获取源…

C语言.表白神器.爱你之心之闪耀

前言 爱你之心之闪耀&#xff0c;这个名字比较沙雕哈哈哈。。。 爱你之心之闪耀前言爱心函数的选取爱心函数1爱心函数2简单爱心粒子发射原理爱心结构一些宏初始化init创建若干爱心并初始化setHeart展示爱心showHeart爱心变大modifyHeart设置音乐主函数Love.hLove.cpp祝有情人&a…

【有营养的算法笔记】一文轻松学会高精度算法(加减乘除)

&#x1f451;作者主页&#xff1a;进击的安度因 &#x1f3e0;学习社区&#xff1a;进击的安度因&#xff08;个人社区&#xff09; &#x1f4d6;专栏链接&#xff1a;有营养的算法笔记 文章目录一、前言二、高精度加法1、思想及模板2、代码实现三、高精度减法1、思路及模板2…

电脑一键重装系统卡在正在准备就绪怎么办

最近有些用户想要给电脑换新的系统使用&#xff0c;选择一键重装工具重装&#xff0c;但结果卡住了&#xff0c;小白一键重装系统卡在正在准备就绪怎么办?下面小编就教下大家小白一键重装系统卡在正在准备就绪怎么办的解决办法。 工具/原料&#xff1a; 系统版本&#xff1a;…

七 近代史案例欣赏

首先打开我们的编译器&#xff0c;EgretWing,新建一个Egret项目。 新建好后如下图&#xff1a; 主要文件夹介绍 libs:包类文件夹 resource&#xff1a;资源文件夹 src&#xff1a;编写代码文件夹 template&#xff1a;前端文件夹 代码编写 1 打开src中Main.ts文件找到crea…

Scala中的协变点、逆变点、不变点如何确定?

阅读《scala编程》时&#xff0c;我们知道了类的类型参数是可以型变&#xff08;variance&#xff09;的。型变包含以下三种&#xff1a; 协变&#xff08;convariant&#xff09;&#xff1a;如果S是T的子类型&#xff0c;则C1[S]也是C1[T]的子类型&#xff0c;则称C1在类型参…

leetcode 208. 实现 Trie (前缀树)【字典树(前缀树)的介绍与思路整理】

题目 Trie&#xff08;发音类似 “try”&#xff09;或者说 前缀树 是一种树形数据结构&#xff0c;用于高效地存储和检索字符串数据集中的键。这一数据结构有相当多的应用情景&#xff0c;例如自动补完和拼写检查。 请你实现 Trie 类&#xff1a; Trie() 初始化前缀树对象。…

HCL Notes/Domino 12.0.2版本正式发布

大家好&#xff0c;才是真的好。 之前代号为多瑙河版本的Notes/Domino产品&#xff0c;昨天晚上正式露出了神秘的面纱&#xff0c;版本号也正式定为12.0.2。从版本上来看&#xff0c;是12.0版本的小版本&#xff0c;但从功能和特性上来说&#xff0c;这完全就是一个大版本。 …

Duboo优雅关闭(附源码分析)

Dubbo优雅关闭 1. 关闭有什么问题 当服务提供方要上线的时候&#xff0c;一般是通过部署系统完成实例重启。在这个过程中&#xff0c;服务提供方的团队并不会事先告诉调用方他们需要操作哪些机器&#xff0c;从而让调用方去事先切走流量。而对调用方来说&#xff0c;它也无法…