Heim  >  Artikel  >  Betrieb und Instandhaltung  >  Warum ist Nginx so schnell?

Warum ist Nginx so schnell?

王林
王林nach vorne
2020-10-20 17:25:172797Durchsuche

Warum ist Nginx so schnell?

Zunächst müssen wir wissen, dass Nginx ein Multiprozess- (Single-Thread) und Mehrkanal-IO-Wiederverwendungsmodell verwendet. Nginx verwendet E/A-Multiplexing-Technologie und wird zu einem „gleichzeitig ereignisgesteuerten“ Server.

(Empfohlenes Tutorial: nginx-Tutorial)

Warum ist Nginx so schnell?

Multiprozess-Arbeitsmodus

Nach dem Start von Nginx gibt es einen Masterprozess und mehrere unabhängige Arbeitsprozesse. Der Master empfängt Signale von der Außenwelt und sendet Signale an jeden Worker-Prozess. Jeder Prozess kann die Verbindung verarbeiten. Der Masterprozess kann den Ausführungsstatus des Arbeitsprozesses überwachen. Wenn der Arbeitsprozess beendet wird (unter ungewöhnlichen Umständen), wird automatisch ein neuer Arbeitsprozess gestartet.

Achten Sie auf die Anzahl der Worker-Prozesse, die normalerweise auf die Anzahl der CPU-Kerne der Maschine festgelegt ist. Denn mehr Worker führen nur dazu, dass Prozesse miteinander um die CPU konkurrieren, was zu unnötigen Kontextwechseln führt.

Die Verwendung des Multiprozessmodus verbessert nicht nur die Parallelitätsrate, sondern macht die Prozesse auch voneinander unabhängig. Wenn ein Worker-Prozess hängen bleibt, hat dies keine Auswirkungen auf andere Worker-Prozesse.

Thundering Herd Phenomenon

Der Hauptprozess (Master-Prozess) erstellt zunächst einen Sock-Dateideskriptor zur Überwachung über socket() und verzweigt sich dann, um einen untergeordneten Prozess (Worker-Prozess) zu generieren. Der untergeordnete Prozess erbt den Sockfd von Der übergeordnete Prozess (Socket-Dateideskriptor) und der untergeordnete Prozess erstellen nach Accept () einen verbundenen Deskriptor und kommunizieren dann über den verbundenen Deskriptor mit dem Client.

Da also alle untergeordneten Prozesse den Sockfd des übergeordneten Prozesses erben, erhalten alle untergeordneten Prozesse Benachrichtigungen und „rennen“, um eine Verbindung damit herzustellen. Dies wird als „Donnerherden-Phänomen“ bezeichnet. Eine große Anzahl von Prozessen wird aktiviert und angehalten, und nur ein Prozess kann die Verbindung akzeptieren (), was natürlich Systemressourcen verbraucht.

Nginx‘ Umgang mit dem Phänomen der donnernden Herde

Nginx stellt einen Accept_Mutex bereit, bei dem es sich um eine gemeinsame Sperre handelt, die zum Akzeptieren hinzugefügt wird. Das heißt, jeder Arbeitsprozess muss die Sperre erwerben, bevor er Accept ausführen kann. Wenn er sie nicht erwerben kann, gibt er die Ausführung von Accept() auf. Mit dieser Sperre wird nur ein Prozess gleichzeitig accpet() ausführen, sodass es kein Donnerherdenproblem gibt. Accept_mutex ist eine steuerbare Option, die wir explizit deaktivieren können. Sie ist standardmäßig aktiviert.

Detaillierte Erläuterung des Nginx-Prozesses

Nach dem Start von Nginx gibt es einen Master-Prozess und mehrere Worker-Prozesse.

Master-Prozess

wird hauptsächlich zur Verwaltung von Arbeitsprozessen verwendet, einschließlich:

Signale von der Außenwelt empfangen und Signale an jeden Arbeitsprozess senden, um den laufenden Status des Arbeitsprozesses zu überwachen (siehe unten). Unter ungewöhnlichen Umständen wird der neue Arbeitsprozess automatisch neu gestartet

Der Masterprozess dient als interaktive Schnittstelle zwischen der gesamten Prozessgruppe und dem Benutzer und überwacht auch den Prozess. Es muss keine Netzwerkereignisse verarbeiten und ist nicht für die Geschäftsausführung verantwortlich. Es verwaltet lediglich Arbeitsprozesse, um Funktionen wie Dienstneustart, reibungsloses Upgrade, Protokolldateiersetzung und Konfigurationsdateien zu implementieren, die in Echtzeit wirksam werden.

Um Nginx zu steuern, müssen wir lediglich durch Kill ein Signal an den Master-Prozess senden. Beispielsweise weist kill -HUP pid Nginx an, Nginx ordnungsgemäß neu zu starten. Normalerweise verwenden wir dieses Signal, um Nginx neu zu starten oder die Konfiguration neu zu laden. Da es ordnungsgemäß neu gestartet wird, wird der Dienst nicht unterbrochen. Was macht der Master-Prozess, nachdem er das HUP-Signal empfangen hat?

Nach Erhalt des Signals lädt der Master-Prozess zunächst die Konfigurationsdatei neu, startet dann einen neuen Worker-Prozess und sendet Signale an alle alten Worker-Prozesse, um ihnen mitzuteilen, dass sie ordnungsgemäß in den Ruhestand gehen können. Nachdem der neue Worker gestartet wurde, wird er gestartet Neue Anfragen empfangen,

Nach dem Empfang des Signals vom Master empfängt der alte Worker keine neuen Anfragen mehr und wird beendet, nachdem alle unverarbeiteten Anfragen im aktuellen Prozess verarbeitet wurden.

Natürlich ist das direkte Senden von Signalen an den Masterprozess eine ältere Betriebsmethode. Nach der Nginx-Version 0.8 wurden eine Reihe von Befehlszeilenparametern eingeführt, um unsere Verwaltung zu erleichtern. Beispielsweise dient ./nginx -s reload dazu, Nginx neu zu starten, und ./nginx -s stop dient dazu, die Ausführung von Nginx zu stoppen. Wie? Nehmen wir als Beispiel Reload. Wir sehen, dass wir beim Ausführen des Befehls einen neuen Nginx-Prozess starten. Nachdem der neue Nginx-Prozess den Reload-Parameter analysiert hat, wissen wir, dass unser Zweck darin besteht, Nginx so zu steuern, dass er die Konfigurationsdatei neu lädt sendet ein Signal an den Master-Prozess, und die nächste Aktion ist dieselbe, als ob wir das Signal direkt an den Master-Prozess senden würden.

Arbeitsprozess

Grundlegende Netzwerkereignisse werden im Worker-Prozess verarbeitet. Mehrere Worker-Prozesse sind Peer-to-Peer. Sie konkurrieren gleichermaßen um Anfragen von Kunden und jeder Prozess ist unabhängig voneinander. Eine Anfrage kann nur in einem Arbeitsprozess verarbeitet werden, und ein Arbeitsprozess kann keine Anfragen von anderen Prozessen verarbeiten. Die Anzahl der Arbeitsprozesse kann im Allgemeinen so eingestellt werden, dass sie mit der Anzahl der CPU-Kerne der Maschine übereinstimmt. Der Grund dafür ist untrennbar mit dem Prozessmodell und dem Ereignisverarbeitungsmodell von Nginx verbunden.

Arbeitsprozesse sind gleich und jeder Prozess hat die gleiche Möglichkeit, Anfragen zu bearbeiten. Wenn wir einen HTTP-Dienst auf Port 80 bereitstellen und eine Verbindungsanfrage eingeht, kann jeder Prozess die Verbindung verarbeiten. Zunächst wird jeder Worker-Prozess vom Master-Prozess abgezweigt. Im Master-Prozess wird zunächst der abzuhörende Socket (listenfd) eingerichtet und anschließend werden mehrere Worker-Prozesse abgezweigt. Der Listenfd aller Worker-Prozesse wird lesbar, wenn eine neue Verbindung eintrifft. Um sicherzustellen, dass nur ein Prozess die Verbindung verarbeitet, greifen alle Worker-Prozesse vor der Registrierung des Listenfd-Leseereignisses auf den Aufruf des Listenfd-Lesevorgangs zurück Accept im Leseereignis, um die Verbindung zu akzeptieren. Wenn ein Arbeitsprozess die Verbindung akzeptiert, beginnt er mit dem Lesen der Anfrage, dem Parsen der Anfrage, der Verarbeitung der Anfrage, der Generierung von Daten, sendet sie dann an den Client zurück und trennt schließlich die Verbindung. So sieht eine vollständige Anfrage aus. Wir können sehen, dass eine Anfrage vollständig vom Worker-Prozess verarbeitet wird und nur in einem Worker-Prozess verarbeitet wird.

Worker-Prozess-Workflow

Wenn ein Worker-Prozess die Verbindung akzeptiert (), beginnt er, die Anfrage zu lesen, die Anfrage zu analysieren, die Anfrage zu verarbeiten, Daten zu generieren, sie an den Client zurückzugeben und schließlich die Verbindung zu trennen A vollständige Anfrage. Eine Anfrage wird vollständig vom Arbeitsprozess bearbeitet und kann nur in einem Arbeitsprozess bearbeitet werden.

Vorteile dieser Vorgehensweise:

Einsparung des durch Sperren verursachten Overheads. Jeder Arbeitsprozess ist ein unabhängiger Prozess, teilt keine Ressourcen und erfordert keine Sperre. Gleichzeitig wird die Programmierung und Fehlerbehebung wesentlich komfortabler. Unabhängige Prozesse reduzieren Risiken. Durch die Verwendung unabhängiger Prozesse kann verhindert werden, dass sich andere Prozesse gegenseitig beeinflussen, nachdem ein Prozess beendet wurde und der Dienst nicht unterbrochen wird. Der Masterprozess startet schnell neue Arbeitsprozesse. Natürlich kann der Arbeitsprozess auch unerwartet beendet werden.

Im Multiprozessmodell kann jeder Prozess/Thread nur einen IO-Kanal verarbeiten. Wie geht Nginx also mit mehreren IO-Kanälen um?

Wenn IO-Multiplexing nicht verwendet wird, kann in einem Prozess nur eine Anfrage gleichzeitig verarbeitet werden, z. B. die Ausführung von Accept(). Wenn keine Verbindung besteht, blockiert das Programm hier, bis eine Verbindung hergestellt wird, bevor dies möglich ist Weiterführen.

Und Multiplexing ermöglicht es uns, die Kontrolle nur dann an das Programm zurückzugeben, wenn ein Ereignis eintritt, während der Kernel zu anderen Zeiten den Prozess anhält und sich im Standby-Modus befindet.

Kern: Das von Nginx verwendete IO-Multiplex-Modell epoll

Beispiel: Nginx registriert ein Ereignis: „Wenn eine Verbindungsanfrage von einem neuen Client eintrifft, benachrichtigen Sie mich erneut. Danach kommt nur noch die Verbindungsanfrage.“ server Accept() wird ausgeführt, um die Anfrage zu empfangen. Wenn Sie beispielsweise eine Anfrage an einen Upstream-Server (z. B. PHP-FPM) weiterleiten und auf die Rückgabe der Anfrage warten, blockiert der Verarbeitungsarbeiter hier nicht. Nach dem Senden der Anfrage wird ein Ereignis registriert: „Wenn der Puffer empfängt.“ Daten, sagen Sie es mir und ich werde es erneut einlesen“, sodass der Prozess in den Leerlauf wechselt und auf das Eintreten des Ereignisses wartet.

Das obige ist der detaillierte Inhalt vonWarum ist Nginx so schnell?. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!

Stellungnahme:
Dieser Artikel ist reproduziert unter:juejin.im. Bei Verstößen wenden Sie sich bitte an admin@php.cn löschen