前言
近期在工作中,遇到了一次很有意思的内存透露,把排查过程和思路记下来,供大家参考和学习,如有不正确的,欢送斧正。
起因
最近几天很多半托管客户,忽然报连贯服务失败,登上服务器后查看内存很高,为了让客户尽快恢复业务,运维共事第一工夫抉择了重启。
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
找到以后堆栈中应用http中央,排查代码,查看代码有可能没close连贯的中央。
修复好代码,上线后,重启过程,在察看发现内存很安稳,关上的文件数也逐步安稳。
你认为这么简略就完事了?如果就这么简略,我就不会写这篇文章了。
第二天,第三天陆续有其余半托管客户找过去,同样的问题,内存透露,最大文件数始终居高不下,直到达到限度。
和下面的客户一样,修复同样的代码后,均都复原了失常。
发问
1、为什么都是半托管的客户报这个问题,私有云未有客户反馈
2、这些半托管的客户为了稳固,代码曾经很久没降级,代码都是2021年的,为什么都跟磋商好似的,一起报问题,难道我有bug吸引体质?
3、为什么这些客户,物理机房隔离,问题表象却都一样?
4、客户须要一个正当的解释,我总不能说网络抽风了吧?
所有不合理的中央,其实都有正当的解释
半托管:后端服务和敏感数据在客户机房,前端网页在私有云。
理性分析
因为都是半托管客户,又都是因为fd太多,导致的内存透露。
那咱们有一点是能够必定的,那就是连贯过多,导致fd激增,既然是网络问题,那咱们就应用 万能法令 (遇事不决,先抓个包)
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、拜访内网的https受影响不
答:上图就是拜访https的服务,会受到影响
8、设置chrome://flags/#block-insecure-private-network-requests 能够防止不
答:我测试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,以及其余须要的标头。
响应示例
<pre class="prettyprint hljs groovy">HTTP/1.1 204 No Content
Access-Control-Allow-Origin: https://foo.example
Access-Control-Allow-Private-Network: true</pre>
或者
<pre class="prettyprint hljs groovy">HTTP/1.1 200 No Content
Access-Control-Allow-Origin: https://foo.example
Access-Control-Allow-Private-Network: true</pre>
10、服务端要不要兼容更新
答:我认为是有必要的,当初chrome发动options申请,你响应或者不响应都不会阻止后续的申请,然而如果他那天在自动更新,你如果未失常解决options申请,就不发送后续业务申请,
嗯。。。我曾经联想到了一大部分程序员连夜加班修bug的局面了。