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 代理服务器。
我正在使用本机 net
和 dgram
库来打开 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 <nodejs pid>
开始调试
在 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%