Heim >Backend-Entwicklung >PHP-Tutorial >Nginx-Grundkonzepte – Verbindung

Nginx-Grundkonzepte – Verbindung

WBOY
WBOYOriginal
2016-08-08 09:27:41895Durchsuche
In Nginx ist die Verbindung eine Kapselung der TCP-Verbindung, einschließlich des verbundenen Sockets, Leseereignisses und Schreibereignisses. Mit der von Nginx gekapselten Verbindung können wir Nginx problemlos für die Abwicklung verbindungsbezogener Angelegenheiten verwenden, z. B. für den Verbindungsaufbau, das Senden und Empfangen von Daten usw. Die Verarbeitung von HTTP-Anfragen in Nginx basiert auf einer Verbindung, sodass Nginx nicht nur als Webserver, sondern auch als Mailserver verwendet werden kann. Natürlich können wir über die von Nginx bereitgestellte Verbindung mit jedem Backend-Dienst umgehen. In Kombination mit dem Lebenszyklus einer TCP-Verbindung werfen wir einen Blick darauf, wie Nginx mit einer Verbindung umgeht. Beim Start von Nginx wird zunächst die Konfigurationsdatei analysiert, um den zu überwachenden Port und die IP-Adresse abzurufen. Anschließend wird im Nginx-Masterprozess zunächst der Überwachungs-Socket initialisiert (Socket erstellen, Addrreuse und andere Optionen festlegen und anbinden). den angegebenen IP-Adressport, dann abhören) und dann mehrere untergeordnete Prozesse austeilen, und dann konkurrieren die untergeordneten Prozesse um die Annahme neuer Verbindungen. An diesem Punkt kann der Client eine Verbindung zu Nginx initiieren. Wenn der Client und der Server über einen Drei-Wege-Handshake eine Verbindung herstellen, akzeptiert ein Unterprozess von Nginx erfolgreich, ruft den Socket der hergestellten Verbindung ab und erstellt dann die Kapselung der Verbindung durch Nginx, dh die Struktur ngx_connection_t. Als nächstes richten Sie die Verarbeitungsfunktionen für Lese- und Schreibereignisse ein und fügen Lese- und Schreibereignisse hinzu, um Daten mit dem Client auszutauschen. Schließlich schließt Nginx oder der Client die Verbindung aktiv. An diesem Punkt wird eine Verbindung beendet. Natürlich kann Nginx auch als Client verwendet werden, um Daten von anderen Servern anzufordern (z. B. dem Upstream-Modul). Zu diesem Zeitpunkt werden auch die mit anderen Servern erstellten Verbindungen in ngx_connection_t gekapselt. Als Client erhält Nginx zunächst eine ngx_connection_t-Struktur, erstellt dann einen Socket und legt die Attribute des Sockets fest (z. B. Nichtblockierung). Fügen Sie dann Lese- und Schreibereignisse hinzu, rufen Sie connect/read/write auf, um die Verbindung aufzurufen, und schließen Sie schließlich die Verbindung und geben Sie ngx_connection_t frei. In Nginx hat jeder Prozess ein maximales Limit für die Anzahl der Verbindungen, das sich vom Systemlimit für fd unterscheidet. Im Betriebssystem können wir über ulimit -n die maximale Anzahl von FDS ermitteln, die ein Prozess öffnen kann, nämlich nofile. Da jede Socket-Verbindung einen FD belegt, wird dadurch auch die maximale Anzahl von Verbindungen unseres Prozesses begrenzt. Dies wirkt sich natürlich auch direkt auf die maximale Anzahl von Parallelitäten aus, die unser Programm unterstützen kann. Wenn der fd aufgebraucht ist, schlägt das Erstellen eines Sockets fehl. Nginx legt die maximale Anzahl der von jedem Prozess unterstützten Verbindungen fest, indem es worker_connectons festlegt. Wenn der Wert größer als nofile ist, beträgt die tatsächliche maximale Anzahl von Verbindungen nofile und Nginx gibt eine Warnung aus. Wenn Nginx implementiert ist, wird es über einen Verbindungspool verwaltet. Jeder Arbeitsprozess verfügt über einen unabhängigen Verbindungspool, und die Größe des Verbindungspools beträgt worker_connections. Was hier im Verbindungspool gespeichert wird, ist eigentlich keine echte Verbindung, sondern lediglich ein Array der ngx_connection_t-Struktur mit der Größe von worker_connections. Darüber hinaus speichert Nginx alle freien ngx_connection_t über eine verknüpfte Liste free_connections. Jedes Mal, wenn eine Verbindung hergestellt wird, wird eine aus der Liste der freien Verbindungen abgerufen. Nach der Verwendung wird sie wieder in die Liste der freien Verbindungen aufgenommen. Hier werden viele Leute die Bedeutung des Parameters worker_connections missverstehen und denken, dass dieser Wert der Maximalwert ist, den Nginx eine Verbindung herstellen kann. Tatsächlich stellt dieser Wert die maximale Anzahl von Verbindungen dar, die von jedem Arbeitsprozess hergestellt werden können. Daher sollte die maximale Anzahl von Verbindungen, die von einem Nginx hergestellt werden können, worker_connections * worker_processes sein. Hier geht es natürlich um die maximale Anzahl von Verbindungen, die bei HTTP-Anforderungen an lokale Ressourcen unterstützt werden können: worker_connections * worker_processes. Wenn HTTP als Reverse-Proxy verwendet wird, beträgt die maximale Anzahl Parallelitäten sollten worker_connections sein. * worker_processes/2. Denn als Reverse-Proxy-Server stellt jede gleichzeitige Verbindung eine Verbindung mit dem Client und eine Verbindung mit dem Back-End-Dienst her, wodurch zwei Verbindungen belegt werden. Nun, wie wir bereits sagten, konkurrieren mehrere inaktive Prozesse um die Verbindung. Es ist leicht zu erkennen, dass dieser Wettbewerb zu Ungerechtigkeit führt. Wenn ein Prozess eine höhere Chance hat, akzeptiert zu werden. Die inaktiven Verbindungen werden bald aufgebraucht sein, wenn nicht im Voraus eine gewisse Kontrolle erfolgt. Wenn eine neue TCP-Verbindung akzeptiert wird, kann die inaktive Verbindung nicht abgerufen und die Verbindung nicht an andere Prozesse übertragen werden, was letztendlich zu diesem TCP führt Die Verbindung kann nicht verarbeitet werden und wird abgebrochen. Das ist offensichtlich unfair. Manche Prozesse haben freie Verbindungen, haben aber keine Chance, diese zu verarbeiten. Manche Prozesse verwerfen künstlich Verbindungen, weil sie keine freien Verbindungen haben. Wie kann man dieses Problem lösen? Erstens muss die Nginx-Verarbeitung zuerst die Option „accept_mutex“ aktivieren. Zu diesem Zeitpunkt fügt nur der Prozess das Accept-Ereignis hinzu. Mit anderen Worten: Nginx steuert, ob der Prozess das Accept-Ereignis hinzufügt. Nginx verwendet eine Variable namens ngx_accept_disabled, um zu steuern, ob um die Accept_mutex-Sperre konkurriert werden soll. Berechnen Sie im ersten Code den Wert von ngx_accept_disabled. Dieser Wert beträgt ein Achtel der Gesamtzahl der Verbindungen in einem einzelnen Nginx-Prozess Die verbleibenden Verbindungen sind kleiner als. Der Wert ist nur dann größer als 0, wenn ein Achtel der Gesamtzahl der Verbindungen vorhanden ist. Je kleiner die Anzahl der verbleibenden Verbindungen ist, desto größer ist der Wert. Wenn Sie sich den zweiten Codeabschnitt ansehen, wird nicht versucht, die Accept_mutex-Sperre zu erhalten, wenn ngx_accept_disabled größer als 0 ist, und ngx_accept_disabled wird um 1 dekrementiert. Daher wird es bei jeder Ausführung hier um 1 dekrementiert, bis es erreicht ist ist kleiner als 0. Das Nichterwerben der Accept_mutex-Sperre ist gleichbedeutend mit dem Verzicht auf die Möglichkeit, die Verbindung zu erhalten. Es ist offensichtlich, dass ngx_accept_disable umso größer ist, je mehr Möglichkeiten es gibt, sodass andere Prozesse die Möglichkeit haben, diese Verbindung zu erhalten Die Sperre wird ebenfalls reduziert. Wenn Sie dies nicht akzeptieren, wird Ihre eigene Verbindung kontrolliert und der Verbindungspool anderer Prozesse verwendet. Auf diese Weise steuert Nginx das Gleichgewicht der Verbindungen zwischen mehreren Prozessen. ngx_accept_disabled = ngx_cycle->connection_n / 8 - ngx_cycle->free_connection_n; if (ngx_accept_disabled > 0) { ngx_accept_disabled--; } else { if (ngx_trylock_accept_mutex(cycle) == NGX_ERROR) { return; } if (ngx_accept_mutex_held) { flags |= NGX_POST_EVENTS; } else { if (timer == NGX_TIMER_INFINITE || timer > ngx_accept_mutex_delay) { timer = ngx_accept_mutex_delay; } } }

Das Obige stellt das Grundkonzept der Nginx-Verbindung vor, einschließlich seiner Aspekte. Ich hoffe, es wird für Freunde hilfreich sein, die sich für PHP-Tutorials interessieren.

Stellungnahme:
Der Inhalt dieses Artikels wird freiwillig von Internetnutzern beigesteuert und das Urheberrecht liegt beim ursprünglichen Autor. Diese Website übernimmt keine entsprechende rechtliche Verantwortung. Wenn Sie Inhalte finden, bei denen der Verdacht eines Plagiats oder einer Rechtsverletzung besteht, wenden Sie sich bitte an admin@php.cn