Erfahren Sie, wie nginx hohe Leistung und Skalierbarkeit erreicht.

Erfahren Sie, wie nginx hohe Leistung und Skalierbarkeit erreicht.

Die Gesamtarchitektur von NGINX ist durch eine Reihe zusammenarbeitender Prozesse gekennzeichnet:

Hauptprozess: verantwortlich für die Ausführung privilegierter Vorgänge, wie das Lesen von Konfigurationsdateien, das Binden von Sockets und das Erstellen/Signalisieren von untergeordneten Prozessen.

Arbeitsprozess: Verantwortlich für den Empfang und die Verarbeitung von Verbindungsanforderungen, das Lesen und Schreiben auf die Festplatte und die Kommunikation mit Upstream-Servern. Wenn NGINX aktiv ist, sind nur die Arbeitsprozesse beschäftigt.

Cache-Loader-Prozess: verantwortlich für das Laden des Festplattencaches in den Speicher. Dieser Prozess wird beim Start ausgeführt und dann beendet.

Cache-Manager-Prozess: verantwortlich für die Organisation der Festplatten-Cache-Daten, um sicherzustellen, dass sie die Grenzen nicht überschreiten. Dieser Vorgang wird zeitweise ausgeführt.

Der Schlüssel zur hohen Leistung und Skalierbarkeit von NGINX liegt in zwei grundlegenden Designentscheidungen:

Begrenzen Sie die Anzahl der Arbeitsprozesse so weit wie möglich, um den durch Kontextwechsel verursachten Mehraufwand zu reduzieren. Die standardmäßige und empfohlene Konfiguration besteht darin, einen Arbeitsprozess pro CPU-Kern zu haben, um die Hardwareressourcen effizient zu nutzen.

Der Arbeitsprozess ist ein Einzelthread und verarbeitet mehrere gleichzeitige Verbindungen auf nicht blockierende Weise.

Jeder NGINX-Arbeitsprozess verarbeitet mehrere Verbindungsanforderungen über eine Zustandsmaschine, die nicht blockierend implementiert ist:

Jeder Arbeitsprozess muss mehrere Sockets verarbeiten, darunter Listening-Sockets und Verbindungs-Sockets.

Wenn der Listening-Socket eine neue Anforderung empfängt, wird ein neuer Verbindungs-Socket geöffnet, um die Kommunikation mit dem Client abzuwickeln.

Wenn ein Ereignis für einen verbundenen Socket eintrifft, vervollständigt der Arbeitsprozess schnell die Antwort und fährt mit der Verarbeitung aller neu empfangenen Ereignisse für alle anderen Sockets fort.

Garrett sagte, dass sich NGINX durch seine Designentscheidungen grundlegend von anderen Webservern unterscheide. Ein typischer Webserver weist jeder Verbindung einen separaten Thread zu. Dadurch wird die Handhabung mehrerer Verbindungen erheblich vereinfacht, weil jede Verbindung als lineare Abfolge mehrerer Schritte betrachtet werden kann. Allerdings entsteht dadurch der Mehraufwand eines Kontextwechsels. Tatsächlich sind Arbeitsthreads die meiste Zeit blockiert und warten auf Clients oder andere Upstream-Server. Wenn die Anzahl gleichzeitiger Verbindungen/Threads, die versuchen, E/A-Vorgänge auszuführen, einen bestimmten Schwellenwert überschreitet oder wenn der Speicher erschöpft ist, werden die Kosten des Kontextwechsels deutlich.

NGINX hingegen ist so konzipiert, dass Arbeitsprozesse den Netzwerkverkehr nur dann blockieren, wenn es keine Arbeit zu erledigen gibt. Darüber hinaus verbraucht jede neue Verbindung nur sehr wenige Ressourcen, darunter nur einen Dateideskriptor und eine kleine Menge an Arbeitsprozessspeicher.

Im Allgemeinen kann jeder Arbeitsvorgang von NGINX nach der Systemoptimierung Hunderte oder Tausende gleichzeitige HTTP-Verbindungen verarbeiten.

Inside NGINX: Wie wir es für Leistung und Skalierbarkeit entwickelt haben

Der Grund für die überlegene Leistung von NGINX liegt in seinem Design. Während viele Webserver und Anwendungsserver einfache Thread- oder prozessbasierte Architekturen verwenden, zeichnet sich NGINX durch eine ausgefeilte ereignisgesteuerte Architektur aus, die Zehntausende gleichzeitige Verbindungen auf moderner Hardware unterstützen kann.

Die Infografik „Inside NGINX“ deckt alles ab, von einer umfassenden Erkundung der Prozessarchitektur bis hin zu einem Diagramm, wie ein einzelner NGINX-Prozess mehrere Verbindungen verarbeitet. In diesem Artikel werden die Einzelheiten dieser Vorgänge erläutert.

Die Ausgangslage - das NGINX-Prozessmodell

Die Szenerie? Das NGINX-Prozessmodell

Um das Design besser zu verstehen, müssen Sie verstehen, wie NGINX funktioniert. NGINX verfügt über einen Masterprozess (der privilegierte Vorgänge wie das Lesen der Konfiguration und das Binden an Ports ausführt) und eine Reihe von Arbeits- und Hilfsprozessen.

Auf diesem Quad-Core-Server erstellt der NGINX-Masterprozess vier Arbeitsprozesse und zwei Cache-Hilfsprozesse, um den Inhaltscache auf der Festplatte zu verwalten.

Warum ist Architektur wichtig?

Warum ist Architektur wichtig?

Die grundlegende Basis jeder Unix-Anwendung sind Threads oder Prozesse. (Aus der Perspektive des Linux-Betriebssystems sind Threads und Prozesse im Wesentlichen dasselbe; der Hauptunterschied besteht im Ausmaß, in dem sie Speicher gemeinsam nutzen.) Ein Prozess oder Thread ist eine Reihe unabhängiger Anweisungen, die das Betriebssystem zur Ausführung auf einem CPU-Kern planen kann. Die meisten komplexen Anwendungen führen aus zwei Gründen mehrere Threads oder Prozesse parallel aus:

● Es können mehrere Rechnerkerne gleichzeitig genutzt werden.

●Threads und Prozesse erleichtern die Implementierung paralleler Vorgänge (beispielsweise die gleichzeitige Handhabung mehrerer Verbindungen).

Sowohl Prozesse als auch Threads verbrauchen Ressourcen. Sie alle verwenden Speicher und andere Betriebssystemressourcen, was zu häufigem Kernwechsel führt (ein Vorgang, der als Kontextwechsel bezeichnet wird). Die meisten modernen Server können Hunderte kleiner, aktiver Threads oder Prozesse gleichzeitig verarbeiten. Wenn jedoch der Speicher erschöpft ist oder eine hohe E/A-Last zu einer großen Zahl von Kontextwechseln führt, kann die Serverleistung erheblich nachlassen.

Bei Netzwerkanwendungen wird üblicherweise jeder Verbindung ein Thread oder Prozess zugewiesen. Diese Architektur ist einfach zu implementieren, aber wenn die Anwendung Zehntausende gleichzeitige Verbindungen verarbeiten muss, wird die Skalierbarkeit dieser Architektur zum Problem.

Wie funktioniert NGINX?

Wie funktioniert NGINX?

NGINX verwendet ein vorhersagbares Prozessmodell, um verfügbare Hardwareressourcen zu planen:

1. Der Hauptprozess führt privilegierte Vorgänge wie das Lesen der Konfiguration und das Binden von Ports aus und ist auch für das Erstellen untergeordneter Prozesse (die drei folgenden Typen) verantwortlich.

2. Der Cache-Loader-Prozess wird beim Start ausgeführt, lädt den festplattenbasierten Cache in den Speicher und wird dann beendet. Die Planung erfolgt sorgfältig, so dass der Ressourcenbedarf gering ist.

3. Der Cache-Manager-Prozess wird regelmäßig ausgeführt und bereinigt die Einträge aus den Festplatten-Caches, um sie innerhalb des konfigurierten Bereichs zu halten.

4. Arbeitsprozesse sind die Prozesse, die alle eigentlichen Aufgaben ausführen: Handhabung von Netzwerkverbindungen, Lesen und Schreiben von Inhalten auf der Festplatte, Kommunikation mit Upstream-Servern usw.

In den meisten Fällen empfiehlt NGINX, einen Arbeitsprozess pro CPU-Kern auszuführen, um die Hardwareressourcen möglichst effizient zu nutzen. Sie können in Ihrer Konfiguration die folgenden Anweisungen festlegen:

worker_processes auto

Wenn der NGINX-Server läuft, sind nur die Arbeitsprozesse beschäftigt. Jeder Arbeitsprozess verarbeitet mehrere Verbindungen auf eine nicht blockierende Weise, um den Aufwand für Kontextwechsel zu reduzieren.

Jeder Arbeitsprozess ist ein Einzelthread und wird unabhängig ausgeführt. Er greift auf neue Verbindungen zu und verarbeitet sie. Prozesse teilen Cache-Daten, Sitzungspersistenzdaten und andere gemeinsame Ressourcen über den gemeinsamen Speicher.

Arbeitsprozesse innerhalb von NGINX

Im NGINX-Arbeitsprozess

Jeder NGINX-Arbeitsprozess wird mit der NGINX-Konfiguration initialisiert und erhält vom Masterprozess einen Satz Abhörsockets zugewiesen.

NGINX-Arbeitsprozesse hören auf Ereignisse auf Sockets (accept_mutex und Kernel-Socket-Sharding), um zu entscheiden, wann mit der Arbeit begonnen werden soll. Ereignisse werden durch neue Verbindungen initiiert. Diese Verbindungen werden Zustandsmaschinen zugewiesen – die HTTP-Zustandsmaschine wird am häufigsten verwendet, aber NGINX implementiert auch Zustandsmaschinen für Streaming (natives TCP) und eine Reihe von E-Mail-Protokollen (SMTP, IMAP und POP3).

Die Zustandsmaschine ist im Wesentlichen ein Satz von Anweisungen, der NGINX mitteilt, wie eine Anforderung zu verarbeiten ist. Die meisten Webserver, die dieselbe Funktion wie NGINX ausführen, verwenden eine ähnliche Zustandsmaschine – die Implementierung ist lediglich unterschiedlich.

Scheduling-Zustandsmaschine

Planen der Zustandsmaschine

Stellen Sie sich eine Zustandsmaschine wie die Schachregeln vor. Jede HTTP-Transaktion ist ein Schachspiel. Auf der einen Seite des Schachbretts sitzt der Webserver – ein Schachgroßmeister, der schnell Entscheidungen treffen kann. Auf der anderen Seite befindet sich der Remote-Client – ​​ein Webbrowser, der über ein relativ langsames Netzwerk auf eine Site oder Anwendung zugreift.

Die Wettbewerbsregeln können jedoch kompliziert sein. Beispielsweise muss ein Webserver möglicherweise mit anderen Parteien kommunizieren (Proxy für eine Upstream-Anwendung) oder mit einem Authentifizierungsserver kommunizieren. Durch Fremdmodule des Webservers können die Spielregeln zudem erweitert werden.

Blockierender Zustandsautomat

Eine blockierende Zustandsmaschine

Erinnern Sie sich an unsere vorherige Beschreibung von Prozessen und Threads: eine Reihe unabhängiger Befehlssätze, die vom Betriebssystem geplant und auf dem CPU-Kern ausgeführt werden können. Die meisten Webserver und Webanwendungen verwenden zum Spielen dieses Schachspiel ein Modell mit einer Verbindung/einem Prozess oder einer Verbindung/einem Thread. Jeder Prozess oder Thread enthält eine Anweisung, das Spiel bis zum Ende zu spielen. Während dieses Vorgangs wird der Prozess vom Server ausgeführt und verbringt die meiste Zeit „blockiert“, während er darauf wartet, dass der Client seine nächste Aktion abschließt.

1. Der Webserverprozess wartet auf dem Abhörsocket auf neue Verbindungen (neue, vom Client initiierte Übereinstimmungen).

2. Nachdem ein neues Spiel gestartet wurde, beginnt der Prozess zu arbeiten. Nach jedem Zug wechselt er in einen blockierten Zustand und wartet darauf, dass der Client den nächsten Zug macht.

3. Sobald das Spiel beendet ist, prüft der Webserverprozess, ob der Client ein neues Spiel starten möchte (dies entspricht einer Keepalive-Verbindung). Wenn die Verbindung geschlossen wird (der Client verlässt die Verbindung oder es kommt zu einer Zeitüberschreitung), kehrt der Webserverprozess in den Abhörzustand zurück und wartet auf eine neue Übereinstimmung.

Ein wichtiger Punkt, den Sie bedenken sollten, ist, dass jede aktive HTTP-Verbindung (jedes Schachspiel) einen dedizierten Prozess oder Thread (einen Großmeisterspieler) erfordert. Diese Architektur lässt sich sehr einfach mit Modulen von Drittanbietern erweitern („neue Regeln“). Allerdings besteht hier ein großes Ungleichgewicht: Eine einfache HTTP-Verbindung, die durch einen Dateideskriptor und eine kleine Speichermenge dargestellt wird, wird einem einzelnen Prozess oder Thread zugeordnet, bei dem es sich um sehr schwergewichtige Betriebssystemobjekte handelt. Dies ist zwar programmiertechnisch praktisch, führt jedoch zu enormer Verschwendung.

NGINX ist der wahre Meister

NGINX ist ein wahrer Großmeister

Vielleicht haben Sie schon von dem Turnier gehört, bei dem ein Schachgroßmeister gegen Dutzende Gegner gleichzeitig antritt.

Kiril Georgiev spielte in Sofia, der Hauptstadt Bulgariens, gegen 360 Spieler gleichzeitig und erreichte schließlich einen Rekord von 284 Siegen, 70 Unentschieden und 6 Niederlagen.

So spielen NGINX-Mitarbeiter „Schach“. Jeder Arbeitsprozess ist ein Großmeister (denken Sie daran: normalerweise belegt jeder Arbeitsprozess einen CPU-Kern) und kann gegen Hunderte (eigentlich Tausende) von Spielern gleichzeitig spielen.

1. Der Arbeitsprozess wartet auf Ereignisse am Listening-Socket und am Verbindungs-Socket.

2. Auf dem Socket treten Ereignisse auf und der Arbeitsprozess verarbeitet diese Ereignisse.

●Ereignisse am Listening-Socket bedeuten: Der Client hat ein neues Spiel gestartet. Der Arbeitsprozess erstellt einen neuen Verbindungssocket.

●Ein Ereignis am Verbindungs-Socket bedeutet: Der Client hat eine Schachfigur bewegt. Der Arbeitsprozess reagiert schnell.

Der Arbeitsprozess wird im Netzwerk nie angehalten, er wartet immer auf die Antwort seines „Gegners“ (Clients). Wenn es die Spielsteine ​​für dieses Spiel bewegt hat, kann es sofort mit dem nächsten Spiel fortfahren oder sich einem neuen Gegner stellen.

Warum ist es schneller als eine blockierende Multiprozessarchitektur?

Warum ist dies schneller als eine blockierende Multiprozessarchitektur?

NGINX ist gut skalierbar und unterstützt Zehntausende Verbindungen pro Arbeitsprozess. Jede neue Verbindung erstellt einen anderen Dateideskriptor und verbraucht eine kleine Menge zusätzlichen Speichers im Arbeitsprozess. Die Mehrkosten für jede Verbindung sind sehr gering. Der NGINX-Prozess kann eine feste CPU-Auslastung aufrechterhalten. Es gibt auch weniger Kontextwechsel, wenn keine Arbeit ansteht.

Im blockierenden Modell mit einer Verbindung/einem Prozess erfordert jede Verbindung viele zusätzliche Ressourcen und Overhead, und Kontextwechsel (von einem Prozess zum anderen) sind sehr häufig.

Wenn Sie mehr erfahren möchten, lesen Sie diesen Artikel zur NGINX-Architektur von Andrew Alexeev, VP of Corporate Development und Mitbegründer von NGINX.

Durch die richtige Systemoptimierung kann NGINX so skaliert werden, dass es Hunderttausende gleichzeitige HTTP-Verbindungen pro Arbeitsprozess verarbeiten kann, ohne dass bei Verkehrsspitzen Informationen (neue Races) verloren gehen.

Konfigurationsupdates und NGINX-Upgrades

Aktualisieren der Konfiguration und Upgrade von NGINX

Die NGINX-Prozessarchitektur, die nur aus einer kleinen Anzahl von Arbeitsprozessen besteht, macht Aktualisierungen der Konfiguration und sogar der Binärdateien selbst sehr effizient.

Das Aktualisieren der NGINX-Konfiguration ist ein sehr einfacher, leichter und zuverlässiger Vorgang. Führen Sie einfach den Reload-Befehl von nginx aus, der die Konfiguration auf der Festplatte überprüft und ein SIGHUP-Signal an den Hauptprozess sendet.

Wenn der Hauptprozess das SIGHUP-Signal empfängt, führt er zwei Aktionen aus:

1. Laden Sie die Konfiguration neu und erstellen Sie einen neuen Satz funktionierender Prozesse. Diese neuen Arbeitsprozesse beginnen sofort damit, Verbindungen anzunehmen und den Datenverkehr zu verarbeiten (unter Verwendung der neuen Konfiguration).

2. Senden Sie ein Signal, um den alten Arbeitsprozess anzuweisen, stillschweigend zu beenden. Diese alten Prozesse akzeptieren keine neuen Verbindungen mehr. Sobald die von ihnen verarbeitete HTTP-Anfrage abgeschlossen ist, schließen sie die Verbindung sauber. Sobald alle Verbindungen geschlossen sind, wird der Arbeitsprozess beendet.

Dieser Vorgang führt zu einer kleinen Spitze bei der CPU- und Speicherauslastung, die jedoch im Vergleich zum Laden von Ressourcen aus aktiven Verbindungen vernachlässigbar ist. Sie können die Konfiguration mehrmals pro Sekunde neu laden. In seltenen Fällen kann es zu Problemen kommen, während Generationen von Mitarbeitern darauf warten, dass die Verbindungen geschlossen werden. Doch selbst wenn Probleme auftreten, werden diese umgehend behoben.

Der binäre Upgrade-Prozess für NGINX ist sogar noch erstaunlicher – Sie können NGINX selbst im laufenden Betrieb aktualisieren, ohne dass es zu Verbindungsabbrüchen, Ausfallzeiten oder Dienstunterbrechungen auf dem Server kommt.

Der Binäraktualisierungsprozess ähnelt Konfigurationsaktualisierungen. Der neue NGINX-Masterprozess läuft parallel zum ursprünglichen Masterprozess und sie teilen sich den Listening-Socket. Beide Prozesse sind aktiv und ihre jeweiligen Arbeitsprozesse handhaben ihren eigenen Datenverkehr. Sie können dann den alten Masterprozess und seine Worker auffordern, ordnungsgemäß zu beenden.

Der gesamte Prozess wird unter „Steuerung von NGINX“ ausführlicher beschrieben.

abschließend

Abschluss

Dieses Diagramm der internen Komponenten von NGINX bietet einen umfassenden Überblick über die Funktionsweise von NGINX. Hinter dieser einfachen Erklärung verbergen sich jedoch über ein Jahrzehnt Innovation und Optimierung. Diese Innovationen und Optimierungen ermöglichen eine gute Leistung von NGINX auf unterschiedlicher Hardware und bieten gleichzeitig die Sicherheit und Zuverlässigkeit, die moderne Webanwendungen erfordern.

Das Obige ist der vollständige Inhalt dieses Artikels. Ich hoffe, er wird für jedermanns Studium hilfreich sein. Ich hoffe auch, dass jeder 123WORDPRESS.COM unterstützen wird.

Das könnte Sie auch interessieren:
  • Tutorial zum Aufbau eines Hochleistungs-Load-Balancing-Clusters mit Nginx+Tomcat
  • So erstellen Sie mit Nginx+Tomcat einen Hochleistungs-Load-Balancing-Cluster
  • Centos5.4+Nginx-0.8.50+UWSGI-0.9.6.2+Django-1.2.3 erstellt einen leistungsstarken WEB-Server
  • Zusammenfassung der Konfigurationsmethode zur Hochleistungsoptimierung des Nginx-Servers
  • Leistungsstarker Nginx-HTTP-Server für die Webentwicklung
  • Linux+Nginx+Php zum Erstellen eines leistungsstarken WEB-Servers

<<:  Vergleich verschiedener Möglichkeiten zur Messung der Leistung von JavaScript-Funktionen

>>:  Lösung für EF (Entity Framework)-Einfüge- oder Aktualisierungsfehler

Artikel empfehlen

Die Verwendung von Textbereichen in HTML und häufige Probleme und Fallanalyse

Der Textarea-Tag ist ein HTML-Tag, den wir häufig ...

Tutorial zum Anzeigen und Ändern von MySQL-Zeichensätzen

1. Überprüfen Sie den Zeichensatz 1. Überprüfen S...

Navicat-Verbindung MySQL Fehlerbeschreibungsanalyse

Inhaltsverzeichnis Umfeld Version der virtuellen ...

Beispiele für einige Verwendungstipps für META-Tags in HTML

HTML-Meta-Tag HTML-Meta-Tags können verwendet wer...

Verwenden Sie vue2+elementui für Hover-Prompts

Die Hover-Prompts von Vue2+elementui sind in exte...

Detaillierte Erklärung der Linux-Systemverzeichnisse sys, tmp, usr, var!

Der Wachstumspfad vom Linux-Neuling zum Linux-Mei...

TypeScript-Union-Typen, Schnittmengentypen und Typwächter

Inhaltsverzeichnis 1. Union-Typ 2. Crossover-Typ ...

Implementierungscode des JQuery-Schrittfortschrittsachsen-Plug-Ins

Jeden Tag ein jQuery-Plugin - Schritt-Fortschritt...