Die ultimative Checkliste für die Produktion von Node.js.

Machst du diese Node-Sache richtig in der Produktion? Lassen Sie uns einige häufige Fehler sehen, die Leute machen, wenn sie Node in der Produktion ausführen (direkt aus meinen eigenen Projekten - wie codedamn) und wie sie gemindert werden können.

Sie können dies als Checkliste für die Produktion verwenden, wenn Sie Node-Apps bereitstellen. Da es sich um einen produktionsfertigen Artikel handelt, gelten viele davon nicht, wenn Sie Apps auf Ihrem lokalen System entwickeln.

Führen Sie den Knoten im Cluster-Modus / in separaten Knotenprozessen aus

Denken Sie daran, dass der Knoten Single-Threaded ist. Es kann viele Dinge (wie HTTP-Anforderungen und Lese- / Schreibvorgänge im Dateisystem) an das Betriebssystem delegieren, das es in einer Multithread-Umgebung verarbeitet. Der Code, den SIE schreiben, die Anwendungslogik, wird jedoch immer in einem einzelnen Thread ausgeführt.

Wenn Sie in einem einzelnen Thread ausgeführt werden, ist Ihr Knotenprozess immer nur auf einen einzelnen Kern auf Ihrem Computer beschränkt. Wenn Sie also einen Server mit mehreren Kernen haben, verschwenden Sie Rechenleistung, wenn Sie Node nur einmal auf Ihrem Server ausführen.

Was bedeutet "Node nur einmal ausführen"? Sie sehen, in Betriebssystemen ist ein Scheduler integriert, der dafür verantwortlich ist, wie die Ausführung von Prozessen auf die CPUs der Maschine verteilt wird. Wenn Sie nur zwei Prozesse auf einem 2-Core-Computer ausführen, ist es für das Betriebssystem am besten, beide Prozesse auf separaten Kernen auszuführen, um die maximale Leistung zu erzielen.

Ähnliches muss mit Node gemacht werden. An dieser Stelle haben Sie zwei Möglichkeiten:

  1. Knoten im Cluster-Modus ausführen - Der Cluster-Modus ist eine Architektur, die in den Knoten selbst integriert ist. Mit einfachen Worten, Node teilt mehr eigene Prozesse auf und verteilt die Last über einen einzigen Master-Prozess.
  2. Knotenprozesse unabhängig ausführen - Diese Option unterscheidet sich geringfügig von der oben genannten in dem Sinne, dass Sie jetzt keinen Masterprozess haben, der die untergeordneten Knotenprozesse steuert. Dies bedeutet, dass wenn Sie verschiedene Knotenprozesse erzeugen, diese völlig unabhängig voneinander ausgeführt werden. Kein gemeinsamer Speicher, kein IPC, keine Kommunikation, nada.

Laut einer Stackoverflow-Antwort ist die letztere (Punkt 2) weitaus besser als die erstere (Punkt 1), aber ein wenig schwieriger einzurichten.

Warum? Denn in einer Node-App gibt es nicht nur Anwendungslogik, sondern fast immer, wenn Sie Server in Node-Code einrichten, müssen Sie Ports binden. Eine einzelne Anwendungscodebasis kann denselben Port nicht zweimal auf demselben Betriebssystem binden.

Dieses Problem kann jedoch leicht behoben werden. Umgebungsvariablen, Docker-Container, NGiNX-Frontend-Proxy usw. sind einige der Lösungen hierfür.

Ratenbegrenzung Ihrer Endpunkte

Seien wir ehrlich. Nicht jeder auf der Welt hat die besten Absichten für Ihre Architektur. Sicher, Angriffe wie DDoS sind einfach sehr kompliziert zu mildern, und selbst Giganten wie GitHub fallen aus, wenn so etwas passiert.

Das Mindeste, was Sie tun können, ist zu verhindern, dass ein Script-Kiddie Ihren Server herunterfährt, nur weil Sie einen teuren API-Endpunkt auf Ihrem Server verfügbar gemacht haben, ohne dass eine Ratenbegrenzung vorhanden ist.

Wenn Sie Express mit Node verwenden, gibt es zwei schöne Pakete, die nahtlos zusammenarbeiten, um den Datenverkehr auf Schicht 7 zu begrenzen:

  1. Express Rate Limit - //www.npmjs.com/package/express-rate-limit
  2. Express Slow Down - //www.npmjs.com/package/express-slow-down

Express Slow Down fügt Ihren Anforderungen eine inkrementelle Verzögerung hinzu, anstatt sie zu löschen. Auf diese Weise werden legitime Benutzer, wenn sie versehentlich DDoS verwenden (super Aktivität beim Klicken auf Schaltflächen hier und da), einfach verlangsamt und sind nicht auf die Rate beschränkt.

Wenn andererseits ein Script-Kiddie Skripte ausführt, um den Server herunterzufahren, überwacht und begrenzt der Express-Ratenbegrenzer diesen bestimmten Benutzer, abhängig von der Benutzer-IP, dem Benutzerkonto oder anderen gewünschten Elementen.

Die Ratenbegrenzung könnte (sollte!) Auch auf Schicht 4 angewendet werden (Schicht 4 bedeutet, dass der Datenverkehr blockiert wird, bevor der Inhalt erkannt wird - HTTP), und zwar über die IP-Adresse. Wenn Sie möchten, können Sie eine NGiNX-Regel einrichten, die den Datenverkehr auf Schicht 4 blockiert und die von einer einzelnen IP-Adresse ausgehende Datenverkehrsflut zurückweist, wodurch Ihre Serverprozesse nicht überfordert werden.

Verwenden Sie einen Frontend-Server für die SSL-Beendigung

Node bietet httpssofort Unterstützung für SSL-Handshakes mit dem Browser unter Verwendung des Servermoduls in Kombination mit den erforderlichen SSL-Zertifikaten.

Aber seien wir ehrlich, Ihre Anwendung sollte sich sowieso nicht mit SSL befassen. Dies sollte die Anwendungslogik nicht tun. Ihr Knotencode sollte nur für das verantwortlich sein, was mit der Anforderung geschieht, nicht für die Vor- und Nachbearbeitung von Daten, die auf Ihrem Server ein- und ausgehen.

Die SSL-Beendigung bezieht sich auf die Konvertierung von Datenverkehr von HTTPS in HTTP. Und dafür gibt es viel bessere Tools als Node. Ich empfehle NGiNX oder HAProxy dafür. Beide haben kostenlose Versionen zur Verfügung, die die Arbeit erledigen und die SSL-Beendigung vom Knoten auslagern.

Verwenden Sie einen Frontend-Server für die Bereitstellung statischer Dateien

Verwenden Sie anstelle der integrierten Methoden express.staticzum Bereitstellen statischer Dateien Frontend-Reverse-Proxy-Server wie NGiNX, um statische Dateien von der Festplatte bereitzustellen.

Erstens kann NGiNX dies schneller als Node tun (weil es von Grund auf neu erstellt wurde, um nur das zu tun). Es werden jedoch auch Dateien ausgelagert, die von einem Single-Threaded-Node-Prozess bereitgestellt werden, der seine Taktzyklen für etwas Besseres verwenden könnte.

Nicht nur das - Frontend-Proxyserver wie NGiNX können Ihnen auch dabei helfen, Inhalte mithilfe der GZIP-Komprimierung schneller bereitzustellen. Sie können auch Ablaufheader, Cache-Daten und vieles mehr festlegen, was wir von Node nicht erwarten sollten (Node kann dies jedoch weiterhin tun).

Konfigurieren Sie die Fehlerbehandlung

Durch eine ordnungsgemäße Fehlerbehandlung können Sie stundenlanges Debuggen und den Versuch, schwierige Fehler zu reproduzieren, vermeiden. Auf dem Server ist es besonders einfach, die Architektur für die Fehlerbehandlung einzurichten, da Sie sie ausführen. Ich empfehle Tools wie Sentry with Node, die Sie aufzeichnen, melden und per E-Mail benachrichtigen, wenn der Server aufgrund eines Fehlers im Quellcode abstürzt.

Sobald dies geschehen ist, ist es jetzt an der Zeit, den Server neu zu starten, wenn er abstürzt, damit die gesamte Site nicht stundenlang ausfällt, bis Sie sie manuell wieder aufnehmen.

Hierfür können Sie einen Prozessmanager wie PM2 verwenden. Oder noch besser, verwenden Sie eine Docker-Container-Umgebung mit Richtlinien wie der restart: alwaysrichtigen Einrichtung von Speicher- und Festplattenlimits.

Das Docker-Setup stellt sicher, dass der Prozess auch dann erneut gestartet wird, wenn Ihr Container in OME ausgeführt wird (was in einer PM2-Umgebung möglicherweise nicht der Fall ist, da das Betriebssystem möglicherweise PM2 beendet, wenn irgendwo in einem laufenden Prozess ein Speicherverlust auftritt).

Konfigurieren Sie die Protokolle ordnungsgemäß

Alle Antworten liegen in Protokollen. Server-Hacks, Server-Abstürze, verdächtiges Benutzerverhalten usw. Dazu müssen Sie Folgendes sicherstellen:

  1. Jeder Anforderungsversuch wird mit der IP-Adresse / Anforderungsmethode / dem Zugriffspfad protokolliert, auf die grundsätzlich so viele Informationen wie möglich protokolliert werden können (mit Ausnahme von privaten Informationen wie Passwörtern und Kreditkarteninformationen natürlich).
  2. Dies kann durch das Morgan-Paket erreicht werden
  3. Richten Sie Dateistream-Protokolle in der Produktion anstelle der Konsolenausgabe ein. Dies ist schneller, einfacher zu sehen und ermöglicht das Exportieren von Protokollen in Online-Protokollanzeigedienste.
  4. Nicht alle Protokollnachrichten haben das gleiche Gewicht. Einige Protokolle dienen nur zum Debuggen. Wenn andere vorhanden sind, kann dies auf eine Pants-on-Fire-Situation hinweisen (z. B. einen Server-Hack oder einen nicht autorisierten Zugriff). Verwenden Sie Winston-Logger, um verschiedene Protokollebenen zu protokollieren.
  5. Setup - Log - Rotation , so dass Sie keine Protokollgröße in GBs nach einem Monat oder so, wenn Sie den Server zu sehen.
  6. GZIP Ihre Protokolldateien nach der Rotation. Text ist billig, stark komprimierbar und einfach zu speichern. Sie sollten niemals Probleme mit Textprotokollen haben, solange diese komprimiert sind und Sie einen Server mit einem anständigen Speicherplatz (25 GB +) betreiben.

Fazit

Es ist leicht, einige Praktiken in der Produktion zu beachten, die Ihnen später Tränen und stundenlanges Debuggen ersparen könnten. Stellen Sie sicher, dass Sie diese Best Practices befolgen, und teilen Sie mir Ihre Meinung mit, indem Sie auf meinem Twitter-Handle Hallo sagen.

Wenn Ihnen dieser Artikel gefallen hat, treffen wir uns in den sozialen Medien. Hier ist mein Instagram und Twitter. Ich bin super aktiv und würde gerne plaudern! Lassen Sie uns verbinden.

Frieden!

Mehul