it-swarm.com.de

Die NodeJS-CPU erreicht jeweils eine CPU auf 100%

Ich habe einen SOCKS5-Proxy-Server, den ich in NodeJS. Geschrieben habe. Ich verwende die nativen net- und dgram-Bibliotheken, um TCP- und UDP-Sockets zu öffnen.

Es funktioniert gut für ca. 2 Tage und alle CPUs sind maximal 30%. Nach 2 Tagen ohne Neustart steigt eine CPU auf 100%. Danach wechseln sich alle CPUs ab und bleiben bei jeweils einer CPU zu 100%.

 CPU Spikes

Hier ist ein 7-Tage-Diagramm der CPU-Spitzen:  enter image description here

Ich verwende Cluster zum Erstellen von Instanzen wie:

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

Dies ist die Ausgabe von strace, während sich die CPU auf 100% befindet:

% 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

Und das Knotenprofilergebnis (schwer):

[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

Da ich nur die nativen Bibliotheken verwende, läuft der meiste Code eigentlich auf C++ und nicht auf JS. Jedes Debugging, das ich machen muss, ist in der V8-Engine. Hier ist eine Zusammenfassung des Node-Profilers (für die Sprache):

 [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

Ich hatte den Verdacht, dass möglicherweise der Müllsammler läuft. Aber ich habe die Heap-Größe von Node erhöht und der Speicher scheint in Reichweite zu sein. Ich weiß nicht wirklich, wie ich es debuggen kann, da jede Iteration ungefähr 2 Tage dauert.

Jemand hatte ein ähnliches Problem und hatte Erfolg beim Debuggen? Ich kann jede Hilfe gebrauchen, die ich bekommen kann.

12
Koray Gocmen

Vor einigen Monaten haben wir festgestellt, dass ein anderer Dienst, der auf derselben Box ausgeführt wurde und offene Steckdosen verfolgt, das Problem verursacht hat. Bei diesem Dienst handelt es sich um eine ältere Version, und nach einiger Zeit spuckte die CPU beim Verfolgen der Sockel aus. Durch das Upgrade auf die neueste Version wurden die Probleme mit der CPU behoben.

Lektion gelernt: Manchmal sind Sie es nicht, es sind sie

0
Koray Gocmen

In Ihrer Frage gibt es nicht genügend Informationen, um Ihren Fall zu reproduzieren. Gründe wie das Betriebssystem, die Node.js-Version, Ihre Code-Implementierung usw. können ein Grund für ein solches Verhalten sein.

Es gibt eine Liste bewährter Methoden, mit denen sich dieses Problem beheben oder vermeiden lässt:

  1. Verwendung pm2 als Supervisor für Ihre Node.js-Anwendung.
  2. Debuggen Ihrer Node.js-Anwendung in der Produktion. Dafür:
    • Überprüfen Sie Ihre SSH-Verbindung zum Produktserver
    • binden Sie Ihren Debug-Port mit ssh -N -L 9229:127.0.0.1:9229 [email protected] an localhost
    • starten Sie das Debuggen mit dem Befehl kill -SIGUSR1 <nodejs pid>
    • Öffnen Sie chrome://inspect in Ihrem Chrome oder verwenden Sie einen anderen Debugger für Node.js
  3. Bevor Sie zur Produktion gehen:
1
galkin