node进程cpu 100%问题排查

案情描述

现象:监控系统显示,官网的服务每个月总有那么几天会烧脑,单台服务器qps 20以内的前提下,从某一刻开始,node进程持续性消耗cpu100%,并且在剔除流量后,居高不下。

问题:cpu持续性被单个服务消耗,既影响服务本身功能和用户体验,也威胁到其他系统和进程的正常运行,更重要的是,存在随时发生生产故障的可能性
node进程cpu占比

应急措施

之前出现问题时,在不能快速定位到具体原因的尴尬前提下,选择了快速执行B计划应急

具体措施:运维对官网服务扩容,通过增加集群数量分担部分压力(其实没什么流量压力,只是因为cpu100%的那几台服务,响应能力变弱了,搞得人和服务器都压力山大的样子),验证新集群可以正常提供服务后,接入流量,并摘除问题服务器的流量,以保证官网服务的正常

搜集证据

问题服务器摘除流量后,就可以开始尸检了,真正的生产debug就这样发生了,贼尴尬,运维开发协作,上演一场debug秀:
运维:

  1. 从监控入手,过滤出耗时请求,缩小定位范围
  2. 从问题服务器入手,观察cpu,网络等资源的消耗情况
  3. 追踪node进程的系统调用情况,企图了解真正消耗cpu底层调用
  4. 使用上古神器gdb debug进程
  5. 猜测

开发:

  1. 分析运维提供的耗时接口,查看是否存在耗时逻辑
  2. 使用更适配node应用的调试工具,企图生产debug(有兴趣的童鞋可以看下 node应用debug利器
  3. 猜测

证据:所有相关的小伙伴都在尽可能的提取证据,以解开案情疑虑,以下列出证据

  1. pm2 monit,显示node进程cpu占比100%,但每个进程业务日志并不多(当时截图居然只截了左边一半),说明真正的业务压力并不大
    pm2监控
  2. ss -ant | awk ‘{++s[$1]} END {for(k in s) print k,s[k]}’ ,问题服务器的网络连接状态统计如下
FIN_WAIT2 394
LISTEN 7
CLOSE_WAIT 5662
TIME_WAIT 768
ESTABLISHED 570
FIN_WAIT1 1

数据显示大部分网络连接处于close_wait状态,这个状态提供了什么信息呢,先看下这些网络状态的释意

LISTEN:       侦听来自远方的TCP端口的连接请求;
SYN-SENT:     在发送连接请求后等待匹配的连接请求;
SYN-RECEIVED: 在收到和发送一个连接请求后等待对方对连接请求的确认;
ESTABLISHED:  代表一个打开的连接;
FIN-WAIT-1:   等待远程TCP连接中断请求, 或先前的连接中断请求的确认;
FIN-WAIT-2:   从远程TCP等待连接中断请求;
CLOSE-WAIT:   等待从本地用户发来的连接中断请求;
CLOSING:      等待远程TCP对连接中断的确认;
LAST-ACK:     等待原来的发向远程TCP的连接中断请求的确认;
TIME-WAIT:    等待足够的时间以确保远程TCP接收到连接中断请求的确认;
CLOSE:        没有任何连接状态;

也就是说大部分连接在等待用户服务发送最后的连接中断的信号,也就是四次握手(挥手)的第三个阶段没有完成

  1. strace -ffp 11112 -o shial.log ,跟踪进程的系统调用和信号情况
    主线程调用:
    主线程
    一个任务线程调用:
    任务线程
    可以看到的是,主线程和任务线程都在频繁的进行futex调用,而且在反复处理两个内存地址,0x3f0da84,0x3f0da58,并且
    FUTEX_WAIT_PRIVATE这个指令的响应一直是 EAGAIN (Resource temporarily unavailable)
11132线程
futex(0x3f0da84, FUTEX_WAKE_OP_PRIVATE, 1, 1, 0x3f0da80, {
   FUTEX_OP_SET, 0, FUTEX_OP_CMP_GT, 1}) = 1
futex(0x3f0da58, FUTEX_WAKE_PRIVATE, 1) = 0
futex(0x3f0da84, FUTEX_WAKE_OP_PRIVATE, 1, 1, 0x3f0da80, {
   FUTEX_OP_SET, 0, FUTEX_OP_CMP_GT, 1}) = 1
futex(0x3f0da58, FUTEX_WAKE_PRIVATE, 1) = 0
futex(0x3f0da84, FUTEX_WAKE_OP_PRIVATE, 1, 1, 0x3f0da80, {
   FUTEX_OP_SET, 0, FUTEX_OP_CMP_GT, 1}) = 1
futex(0x3f0da58, FUTEX_WAKE_PRIVATE, 1) = 0
futex(0x3f0da84, FUTEX_WAKE_OP_PRIVATE, 1, 1, 0x3f0da80, {
   FUTEX_OP_SET, 0, FUTEX_OP_CMP_GT, 1}) = 1
futex(0x3f0da58, FUTEX_WAKE_PRIVATE, 1) = 0

11135线程
futex(0x3f0da84, FUTEX_WAIT_PRIVATE, 17359164, NULL) = 0
futex(0x3f0da58, FUTEX_WAIT_PRIVATE, 2, NULL) = -1 EAGAIN (Resource temporarily unavailable)
futex
  • 10
    点赞
  • 18
    收藏
    觉得还不错? 一键收藏
  • 4
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值