java中的接口是类吗
276
2022-11-06
你知道吗?chrome自动更新到104版本,居然引起Java服务内存泄漏
前言
近期在工作中,遇到了一次很有意思的内存泄漏,把排查过程和思路记下来,供大家参考和学习,如有不正确的,欢迎指正。
起因
最近几天很多半托管客户,突然报连接服务失败,登上服务器后查看内存很高,为了让客户尽快恢复业务,运维同事第一时间选择了重启。
top图
重启后,内存肉眼可见的速度涨了上来,研发同事判断后,可能之后又需要重启,临时给客户部署了备用服务。(不管三七二十一先扩容)
冰山一角
Too many open files 代表已经到了当前进程可以打开的最大文件数,第一时间选择了先加大当前进程打开的最大文件数,让后续的请求可以正常处理
echo - n "Max open files=85535:85535" > /proc/pid/limits
通过命令查看当前已经打开的文件数
lsof -p pid | wc -l43326
正常的进程不可能打开这么多fd,所以应该存在连接泄漏
lsof - p pid | grep can't identify protocol
jstack打印当前的堆栈
jstack -l pid > pid.txt
找到当前堆栈中使用万能法则 (遇事不决,先抓个包)
tcpdump -i any tcp -w tcp.pcap
抓完包后使用wireshark进行分析,发现有很多OPTIONS请求。
wireshak分析options
waht? 这个请求是使用jsonp的方式,为什么会存在options请求
在查看原本GET请求的内容
在这里插入图片描述
然后在公有云相同的服务器抓了个包,发现只有get请求,没有options请求,那可以说明这个options请求,只有在出现问题的半托管机器上有
但是我们有那么多半托管客户,报问题的却只有几个
大胆假设
我们都知道options是浏览器发的跨域预检请求,那说明这件事和浏览器脱不了干系,通过抓包文件来看,发options请求的浏览器的版本都是chrome 104版本。
嗯,chrome居然又更新了,我们大胆假设一下,内存泄漏和chrome版本有关系。
为了验证我的假设,我找到了chrome的升级说明。
嗯,果然只有假设才会有答案
附上chrome的升级说明。如果打不过也可以看下github的这个说明
• 大概意思就是说:
如果你从公网访问私有网络,那么会在chrome104版本,发option进行预检,该请求带有一个新的标头(Access-Control-Request-Private-Network: true)。 在这个初始阶段,这个请求被发送,但是目前阶段你收到可以不响应,后续的请求还是会正常发送,并不会影响到你的业务,只会在 DevTools 中显示警告
下图带有private的为私有网络
私有网络定义
好家伙我一看,我处理的半托管客户,ip地址都为192x,172x,10x,全都属于私有网络,又都从公有云的网站发起请求,正好符合104版本描述的条件。
而且服务的代码比较老,收到options请求,没有正常释放,导致了内存泄漏。
天啦撸,你能想到一个内存泄漏,居然是因为chrome自动更新导致的吗?
总结
1、为什么都是半托管的客户报这个问题,公有云未有客户反馈
答:只有半托管客户满足公有ip访问私有ip的条件,且部分用户的chrome浏览器自动更新了
2、这些半托管的客户为了稳定,代码已经很久没升级,代码都是2021年的,为什么都跟商量好似的,一起报问题,难道我有bug吸引体质?
答:chrome自动更新导致
3、为什么这些客户,物理机房隔离,问题表象却都一样?
答:chrome自动更新导致,代码版本都比较老
4、客户需要一个合理的解释,我总不能说网络抽风了吧?
答:不知道chrome发表的版本说明,能不能说服客户
5、是不是只有chrome104版本受影响?
答:应该和chrome104同版本的其他浏览器也会受影响,测试edge也会有影响
6、如何判断我的网站受到影响。
答:首先需要满足公网访问私有网络的条件,其次可以在chrome请求或者抓包中,查看请求头有没有该标头
在这里插入图片描述
7、访问内网的可以避免不
答:我测试104版本没效果
9、服务端如何兼容
答:服务器应检查是否存在Access-Control-Request-Private-Network: true标头。如果请求中存在此标头,则服务器应检查Origin标头和请求路径以及任何其他相关信息(例如Access-Control-Request-Headers)以确保请求是安全的。通常,您应该允许访问您控制下的单个源。
一旦您的服务器决定允许该请求,它应该响应204 No Content(或200 OK)必要的 CORS 标头和新的 PNA 标头。这些标头包括Access-Control-Allow-Origin和Access-Control-Allow-Private-Network: true,以及其他需要的标头。
响应示例
HTTP/1.1 204 No ContentAccess-Control-Allow-Origin: true
或者
HTTP/1.1 200 No ContentAccess-Control-Allow-Origin: true
10、服务端要不要兼容更新
答:我认为是有必要的,现在chrome发起options请求,你响应或者不响应都不会阻止后续的请求,但是如果他那天在自动更新,你如果未正常处理options请求,就不发送后续业务请求,
嗯。。。我已经联想到了一大部分程序员连夜加班修bug的场面了。
版权声明:本文内容由网络用户投稿,版权归原作者所有,本站不拥有其著作权,亦不承担相应法律责任。如果您发现本站中有涉嫌抄袭或描述失实的内容,请联系我们jiasou666@gmail.com 处理,核实后本网站将在24小时内删除侵权内容。
发表评论
暂时没有评论,来抢沙发吧~