NodeJS CPU 一次达到 100% 一个 CPU

Posted

技术标签:

【中文标题】NodeJS CPU 一次达到 100% 一个 CPU【英文标题】:NodeJS CPU spikes to 100% one CPU at a time 【发布时间】:2018-01-05 21:38:59 【问题描述】:

我有一个用 NodeJS 编写的 SOCKS5 代理服务器。 我正在使用本机 netdgram 库来打开 TCP 和 UDP 套接字。

它可以正常工作大约 2 天,并且所有 CPU 最高都在 30% 左右。在没有重新启动的 2 天后,一个 CPU 飙升至 100%。之后,所有 CPU 轮流运行,并保持 100% 一次一个 CPU。

这是 CPU 峰值的 7 天图表:

我正在使用集群创建实例,例如:

for (let i = 0; i < Os.cpus().length; i++) 
  Cluster.fork();

这是 strace 在 cpu 为 100% 时的输出:

% time     seconds  usecs/call     calls    errors syscall
------ ----------- ----------- --------- --------- ----------------
99.76    0.294432          79      3733           epoll_pwait
 0.10    0.000299           0      3724        24 futex
 0.08    0.000250           0      3459        15 rt_sigreturn
 0.03    0.000087           0      8699           write
 0.01    0.000023           0       190       190 connect
 0.01    0.000017           0      3212        38 read
 0.00    0.000014           0       420           close
 0.00    0.000008           0       612       180 recvmsg
 0.00    0.000000           0        34           mmap
 0.00    0.000000           0        16           ioctl
 0.00    0.000000           0       190           socket
 0.00    0.000000           0       111           sendmsg
 0.00    0.000000           0       190           bind
 0.00    0.000000           0       482           getsockname
 0.00    0.000000           0       218           getpeername
 0.00    0.000000           0       238           setsockopt
 0.00    0.000000           0       432           getsockopt
 0.00    0.000000           0      3259       104 epoll_ctl
------ ----------- ----------- --------- --------- ----------------
100.00    0.295130                 29219       551 total

和节点配置文件结果(重了):

[Bottom up (heavy) profile]:
Note: percentage shows a share of a particular caller in the total
amount of its parent calls.
Callers occupying less than 1.0% are not shown.

 ticks parent  name
1722861   81.0%  syscall

  28897    1.4%  UNKNOWN

由于我只使用本机库,我的大部分代码实际上是在 C++ 而不是 JS 上运行的。所以我必须做的任何调试都在 v8 引擎中。以下是节点分析器的摘要(针对语言):

 [Summary]:
   ticks  total  nonlib   name
   92087    4.3%    4.5%  javascript
 1937348   91.1%   94.1%  C++
   15594    0.7%    0.8%  GC
   68976    3.2%          Shared libraries
   28897    1.4%          Unaccounted

我怀疑它可能是正在运行的垃圾收集器。但是我增加了节点的堆大小,内存似乎在范围内。我真的不知道如何调试它,因为每次迭代大约需要 2 天。

有人遇到过类似的问题并成功调试了吗?我可以使用我能得到的任何帮助。

【问题讨论】:

100% 保持多长时间?您的图表显示没有 CPU 的平均使用率超过 25%,只有一个 CPU 的平均使用率低于 18%。如果 CPU 在短时间内达到 100%,这不是问题。这只是意味着一个集群在那段时间很忙,如果您要运行一些 CPU 密集型的东西,这既是预期的也是可取的。 每个 cpu 保持在 100% 大约 2 或 3 分钟。但我知道这不是因为 100% 的 cpu 正在工作而所有其他的 cpu 都处于空闲状态,因为在我开始看到 CPU 达到峰值后,服务器停止响应并需要重新启动。我在原始问题中添加了 CPU 的 7 天图表 您是否有任何服务器日志记录可以开始弄清楚在它达到 100% 并停留在那里之前发生了什么?如果没有,那可能就是您需要添加的内容。我不知道有什么方法可以找出导致它达到 100% 的原因。在日志记录或其他形式的调试卡在 100% 之前,您需要慢慢缩小它所做的工作。 我确实有日志记录,但调试问题并没有太大帮助。感谢您的反馈 作为一种变通方法(不是完整的解决方案),对于仅在运行多天后才会出现的问题,通常可以通过每天简单地重新启动每个集群进程来解决它(通常在一天中服务器负载较低的时候)。 【参考方案1】:

在您的问题中,没有足够的信息来重现您的案例。操作系统、Node.js 版本、您的代码实现等可能是导致此类行为的原因。

有可以解决或避免此类问题的最佳实践列表:

    使用 pm2 作为 Node.js 应用程序的主管。 在生产环境中调试您的 Node.js 应用程序。为了那个原因: 检查您与产品服务器的 ssh 连接 使用ssh -N -L 9229:127.0.0.1:9229 root@your-remove-host将调试端口绑定到本地主机 通过命令kill -SIGUSR1 &lt;nodejs pid&gt;开始调试 在 Chrome 中打开 chrome://inspect 或使用任何其他 Node.js 调试器 在投入生产之前: 压力测试 longevity testing

【讨论】:

【参考方案2】:

几个月前,我们意识到在同一个机器上运行的另一个服务正在跟踪打开的套接字,这导致了这个问题。该服务是一个较旧的版本,一段时间后它在跟踪套接字时会增加 CPU。将服务升级到最新版本解决了 cpu 问题。

经验教训:有时不是你,而是他们

【讨论】:

以上是关于NodeJS CPU 一次达到 100% 一个 CPU的主要内容,如果未能解决你的问题,请参考以下文章

为啥用 Regex.IsMatch 检查这个字符串会导致 CPU 达到 100%?

我电脑CPU的使用率突然达到100%静止不动,程序运行缓慢这是为啥?

Hibernate SQL In 子句使 CPU 使用率达到 100%

为啥 C# 中的多线程不能达到 100% CPU?

开会时CPU 飙升100%同事们都手忙脚乱记一次应急处理过程

NodeJS 上传文件 100% cpu 使用率