0
  • 聊天消息
  • 系统消息
  • 评论与回复
登录后你可以
  • 下载海量资料
  • 学习在线课程
  • 观看技术视频
  • 写文章/发帖/加入社区
会员中心
创作中心

完善资料让更多小伙伴认识你,还能领取20积分哦,立即完善>

3天内不再提示

线上四台机器同一时间全部OOM,到底发生了什么?

数据分析与开发 来源:数据分析与开发 2023-02-08 15:28 次阅读

案发现场

昨天晚上突然短信收到 APM (即 Application Performance Management 的简称,我们内部自己搭建了这样一套系统来对应用的性能、可靠性进行线上的监控和预警的一种机制)大量告警画外音: 监控是一种非常重要的发现问题的手段,没有的话一定要及时建立哦

紧接着运维打来电话告知线上部署的四台机器全部 OOM (out of memory, 内存不足),服务全部不可用,赶紧查看问题!

问题排查

首先运维先重启了机器,保证线上服务可用,然后再仔细地看了下线上的日志,确实是因为 OOM 导致服务不可用

680a4348-a761-11ed-bfe3-dac502259ad0.png

第一时间想到 dump 当时的内存状态,但由于为了让线上尽快恢复服务,运维重启了机器,导致无法 dump 出事发时的内存。所以我又看了下我们 APM 中对 JVM 的监控图表

画外音:一种方式不行,尝试另外的角度切入!再次强调,监控非常重要!完善的监控能还原当时的事发现场,方便定位问题。

681ef536-a761-11ed-bfe3-dac502259ad0.png

不看不知道,一看吓一跳,从 16:00 开始应用中创建的线程居然每时每刻都在上升,一直到 3w 左右,重启后(蓝色箭头),线程也一直在不断增长),正常情况下的线程数是多少呢,600!问题找到了,应该是在下午 16:00 左右发了一段有问题的代码,导致线程一直在创建,且创建的线程一直未消亡!查看发布记录,发现发布记录只有这么一段可疑的代码 diff:在 HttpClient 初始化的时候额外加了一个evictExpiredConnections配置

682b5b0a-a761-11ed-bfe3-dac502259ad0.png

问题定位了,应该是就是这个配置导致的!(线程上升的时间点和发布时间点完全吻合!),于是先把这个新加的配置给干掉上线,上线之后线程数果然恢复正常了。那evictExpiredConnections做了什么导致线程数每时每刻在上升呢?这个配置又是为了解决什么问题而加上的呢?于是找到了相关同事来了解加这个配置的前因后果

还原事发经过

最近线上出现不少NoHttpResponseException的异常, 而上面那个配置就是为了解决这个异常而添加的,那是什么导致了这个异常呢?

在说这个问题之前我们得先了解一下 http 的 keep-alive 机制。

先看下正常的一个 TCP 连接的生命周期

6843813a-a761-11ed-bfe3-dac502259ad0.png

可以看到每个 TCP 连接都要经过三次握手建立连接后才能发送数据,要经过四次挥手才能断开连接,如果每个 TCP 连接在 server 返回 response 后都立马断开,则发起多个 HTTP 请求就要多次创建断开 TCP, 这在Http 请求很多的情况下无疑是很耗性能的, 如果在 server 返回 response 不立即断开 TCP 链接,而是复用这条链接进行下一次的 Http 请求,则无形中省略了很多创建 / 断开 TCP 的开销,性能上无疑会有很大提升。

如下图示,左图是不复用 TCP 发起多个 HTTP 请求的情况,右图是复用 TCP 的情况,可以看到发起三次 HTTP 请求,复用 TCP 的话可以省去两次建立 / 断开 TCP 的开销,理论上一个应用只要开启一个 TCP 连接即可,其他 HTTP 请求都可以复用这个 TCP 连接,这样 n 次 HTTP 请求可以省去 n-1 次创建 / 断开 TCP 的开销。这对性能的提升无疑是有巨大的帮助。

6853a646-a761-11ed-bfe3-dac502259ad0.png

回过头来看 keep-alive (又称持久连接,连接复用)做的就是复用连接, 保证连接持久有效。

画外音: Http 1.1 之后 keep-alive 默认支持并开启,目前大部分网站都用了 http 1.1 了,也就是说大部分都默认支持连接复用了

天下没有免费的午餐,虽然 keep-alive 省去了很多不必要的握手/挥手操作,但由于连接长期保活,如果一直没有 http 请求的话,这条连接也就长期闲着了,会占用系统资源,有时反而会比复用连接带来更大的性能消耗。所以我们一般会为 keep-alive 设置一个 timeout, 这样如果连接在设置的 timeout 时间内一直处于空闲状态(未发生任何数据传输),经过 timeout 时间后,连接就会释放,就能节省系统开销。

看起来给 keep-alive 加 timeout 是完美了,但是又引入了新的问题(一波已平,一波又起!),考虑如下情况:

如果服务端关闭连接,发送 FIN 包(注:在设置的 timeout 时间内服务端如果一直未收到客户端的请求,服务端会主动发起带 FIN 标志的请求以断开连接释放资源),在这个 FIN 包发送但是还未到达客户端期间,客户端如果继续复用这个 TCP 连接发送 HTTP 请求报文的话,服务端会因为在四次挥手期间不接收报文而发送 RST 报文给客户端,客户端收到 RST 报文就会提示异常 (即NoHttpResponseException)

我们再用流程图仔细梳理一下上述这种产生NoHttpResponseException的原因,这样能看得更明白一些

686b5fca-a761-11ed-bfe3-dac502259ad0.png

费了这么大的功夫,我们终于知道了产生NoHttpResponseException的原因,那该怎么解决呢,有两种策略

重试,收到异常后,重试一两次,由于重试后客户端会用有效的连接去请求,所以可以避免这种情况,不过一次要注意重试次数,避免引起雪崩!

设置一个定时线程,定时清理上述的闲置连接,可以将这个定时时间设置为 keep alive timeout 时间的一半以保证超时前回收。

evictExpiredConnections就是用的上述第二种策略,来看下官方用法使用说明

Makes this instance of HttpClient proactively evict idle connections from the connection pool using a background thread.

调用这个方法只会产生一个定时线程,那为啥应用中线程会一直增加呢,因为我们对每一个请求都创建了一个 HttpClient! 这样由于创建每一个 HttpClient 实例j时都会调用 evictExpiredConnections,导致有多少请求就会创建多少个定时线程!

还有一个问题,为啥线上四台机器几乎同一时间点全挂呢?因为由于负载均衡,这四台机器的权重是一样的,硬件配置也一样,收到的请求其实也可以认为是差不多的,这样这四台机器由于创建 HttpClient 而生成的后台线程也在同一时间达到最高点,然后同时 OOM。

解决问题

所以针对以上提到的问题,我们首先把 HttpClient 改成了单例,这样保证服务启动后只会有一个定时清理线程,另外我们也让运维针对应用的线程数做了监控,如果超过某个阈值直接告警,这样能在应用 OOM 前及时发现处理。

画外音:再次强调,监控相当重要,能把问题扼杀在摇篮里!

总结

本文通过线上四台机器同时 OOM 的现象,来详细剖析定位了产生问题的原因,可以看到我们在应用某个库时首先要对这个库要有充分的了解(上述 HttpClient 的创建不用单例显然是个问题),其次必要的网络知识还是需要的,所以要成为一个合格的程序员,不光对语言本身有所了解,还要对网络,数据库等也要有所涉猎,这些对排查问题以及性能调优等会有非常大的帮助,再次,完善的监控非常重要,通过触发某个阈值提前告警,可以将问题扼杀在摇篮里!

审核编辑 :李倩

声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉
  • 机器
    +关注

    关注

    0

    文章

    782

    浏览量

    40726
  • APM
    APM
    +关注

    关注

    1

    文章

    71

    浏览量

    13010
  • 线程
    +关注

    关注

    0

    文章

    504

    浏览量

    19682

原文标题:震惊!线上四台机器同一时间全部 OOM,到底发生了什么?

文章出处:【微信号:DBDevs,微信公众号:数据分析与开发】欢迎添加关注!文章转载请注明出处。

收藏 人收藏

    评论

    相关推荐

    如何保证同一时间串口只进行个操作

    程序在运行的时候,有些地方串口是要写入,有些地方是要读取,但两个地方是同时运行的,那么我该怎么去保证在同一时间内,同一个串口只进行个操作,要么读取要么写入。就是如何对这些操作进行
    发表于 02-05 09:31

    可以请教大家个问题吗!大家能帮我看看这个板子是不是上错物料呢!就是同一时

    可以请教大家个问题吗!大家能帮我看看这个板子是不是上错物料呢!就是同一时间生产,可是两个板子就出现两个情况!个板子上的开关芯片内阻抗非常大,个正常! . 因为选用的是美
    发表于 05-01 19:58

    电源电路控制,使用与非门的74,不知道这样的是需要设计个什么样的电路?

    您好:我想做个小型的电路,主要实现以下功能:俩个u***口全部正常无损坏,同一时间如果插入个可以充电传输,另个就断开不能充电传输(
    发表于 04-03 12:01

    请问OLED显示屏可以让整帧画面同一时间显示出来吗,而不是行扫?

    OLED显示屏是否可以让整帧画面同一时间显示出来,而不是行扫?
    发表于 07-23 16:35

    多个SmartXplorer在一台机器上运行

    嗨,我想在一台机器上运行多个smartXplorer运行,即我有两个不同的项目,并希望在同一台机器上运行SmartXplorer。但是,当试图启动第二个SmartXplorer运行时,我被告知它
    发表于 10-17 14:15

    ad9361基带信号输入为什么P路在同一时间周期内携带两个相位相反的信号?

    。 data_p与data_n是组相位相反的信号。为什么P路在同一时间周期内携带两个相位相反的信号? 对后面的DA转换有什么影响??现在在看手册,还没看这方面的解释~~望大神指点!!!! 附上程序图
    发表于 02-25 10:49

    为什么般的无线遥控玩具同一时间只能控制个电机转动

    大家好,我想问个可能很幼稚的问题:为什么般的无线遥控玩具同一时间只能控制个电机转动,买了个2.4GHz的无线遥控器+4通道电机控制,
    发表于 07-02 06:37

    为什么我打印出来的都是同一时间的CPU使用率?

    求助:stm32+ucosii,统计CPU使用率,通过串口打印出来,结果打印出来的都是同一时间的CPU使用率希望大家帮我看下,感激不尽!!!
    发表于 08-19 04:35

    UART和CAN总线在同一时间会怎么样

    )。同时用1至4个串行端口进行SED。我知道可以使用PIC32 RAM来保存缓冲器。也许有更多的背景发生,我不知道。谁有相似的经验,或者我有奇特的软件,使UART和CAN总线在同一时间,以大约相同的速率起具有意想不到的数据?谢
    发表于 04-27 13:39

    可以在同一时间使用STM32WB55的外部RAM和FLASH呢?

    我正在尝试向 STM32WB55 添加外部 FLASH 和 RAM,但他没有 FMC 或 FSMC,并且可以找到与此主题相关的所有资源都使用 FMC 外设,有任何方法可以使用外部 RAM和FLASH在同一时间?我应该为它们都使用 1 QSPI 吗?
    发表于 12-28 06:09

    百度对Robin第一时间做出回答:我没说过

    几个做创投的朋友见面第句话就是问Robin之事是否空穴来风?百度当然是第一时间做了辟谣回应,称已于5月22日收集好证据向公安机关报了案。
    发表于 07-05 15:35 2481次阅读

    高通、博通同一时间大量裁员_商量好了?

    15日最新消息,据路透社报道,美国芯片巨头博通周宣布,在完成对博科通讯系统的收购后,已裁减了约1100名员工,以削减成本。与此同时,另家美国芯片巨头高通15日(上午)也传来裁员消息。据悉,高通数据中心芯片部门将裁减约280名员工。
    的头像 发表于 06-19 16:16 4814次阅读

    微软第一时间采取措施适配搭载M1的macOS

    针对苹果发布的基于ARM机构的M1桌面处理器,微软已经第一时间跟进了。
    的头像 发表于 11-12 14:19 1493次阅读

    现场设备发生故障,虹科物联网HMI第一时间通知相关人员?

    现场设备是保证企业正常生产的关键条件之,当设备发生故障时,如何能够第一时间发现故障并通知相关人员,降低设备故障带来的影响?今天我们将带您了解虹科物联网HMI如何发现设备故障,并第一时间
    的头像 发表于 03-02 13:15 520次阅读
    现场设备<b class='flag-5'>发生</b>故障,虹科物联网HMI第<b class='flag-5'>一时间</b>通知相关人员?

    虹科方案 | 现场设备发生故障,如何第一时间通知相关人员?

    虹科IIoT现场设备发生故障,如何第一时间通知相关人员?虹科方案01前言虹科物联网HMI作为站式物联网解决方案,致力于解决用户在数据采集和可视化、远程监控、边缘计算、软PLC、数据存储(SQL
    的头像 发表于 03-29 15:41 713次阅读
    虹科方案 | 现场设备<b class='flag-5'>发生</b>故障,如何第<b class='flag-5'>一时间</b>通知相关人员?