代码之家  ›  专栏  ›  技术社区  ›  Koray Gocmen

NodeJS CPU峰值达到100%一次一个CPU

  •  13
  • Koray Gocmen  · 技术社区  · 7 年前

    我有一个在NodeJS中编写的SOCKS5代理服务器。 我在利用本地人 net dgram 用于打开TCP和UDP套接字的库。

    它可以正常工作大约2天,所有CPU的最大值都在30%左右。在2天没有重新启动后,一个CPU峰值达到100%。之后,所有CPU轮流运行,每次100%保持一个CPU。

    CPU Spikes

    以下是CPU峰值的7天图表: enter image description here

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

    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
    

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

    有没有人遇到过类似的问题并成功地调试了它?我可以得到任何帮助。

    2 回复  |  直到 7 年前
        1
  •  3
  •   galkin    7 年前

    在你的问题中,没有足够的信息来重现你的情况。像操作系统、节点之类的东西。js版本、代码实现等可能是此类行为的原因。

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

    1. 用法 pm2 作为节点的主管。js应用程序。
    2. 正在调试节点。js在生产中的应用。为此:
      • 检查到产品服务器的ssh连接
      • 使用将调试端口绑定到本地主机 ssh -N -L 9229:127.0.0.1:9229 root@your-remove-host
      • 通过命令启动调试 kill -SIGUSR1 <nodejs pid>
      • 打开 chrome://inspect 在Chrome中,或对节点使用任何其他调试器。js公司
    3. 开始生产前:
        2
  •  1
  •   Koray Gocmen    7 年前

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

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