NodeJS CPU 一次达到 100% CPU

NodeJS CPU spikes to 100% one CPU at a time

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

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

这是 CPU 峰值的 7 天图表:

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

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

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

% 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

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

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

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

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

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

几个月前,我们意识到 运行 在同一个盒子上跟踪打开的套接字的另一个服务导致了这个问题。该服务是旧版本,一段时间后它在跟踪套接字时出现 cpu 峰值。将服务升级到最新版本解决了 cpu 个问题。

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