1. Hintergrund Während des Serverentwicklungsprozesses ist es unvermeidlich, den Dienst neu zu starten, um neuen Code oder neue Konfigurationen zu laden. Wenn sichergestellt werden kann, dass der Dienst während des Serverneustarts nicht unterbrochen wird, können die Auswirkungen des Neustarts auf das Geschäft auf Null reduziert werden. Ich habe kürzlich zum Thema „Smooth Restart“ von Nginx recherchiert und fand es sehr interessant. Ich habe es aufgezeichnet, damit interessierte Studenten es lesen können. 2. Vorgang neu starten
3. Nginx-Implementierung Um den reibungslosen Neustart von nginx zu überprüfen, versuchte der Autor zunächst, beim Start von nginx erneut eine neue Serverinstanz zu starten. Das Ergebnis ist wie in der Abbildung dargestellt: Offensichtlich funktioniert das erneute Öffnen der Serverinstanz nicht, da der alte und der neue Server denselben Port 80 verwenden. Wenn die Socket-Reuseport-Option zur Wiederverwendung von Ports nicht aktiviert ist, schlägt der Bind-Systemaufruf fehl. Standardmäßig versucht Nginx die Bindung fünfmal erneut und wird nach einem Fehler direkt beendet. Nginx muss auf die IPV4-Adresse 0.0.0.0 und die IPV6-Adresse [::] hören, daher werden in der Abbildung 10 Emerg-Protokolle ausgedruckt. Als Nächstes versuchen wir den Befehl „Smooth Restart“, der aus zwei Befehlen besteht: kill -USR2 `cat /var/run/nginx.pid` kill -QUIT `cat /var/run/nginx.pid.oldbin` Der erste Befehl sendet das USR2-Signal an den alten Masterprozess. Die PID des Prozesses wird in der Datei /var/run/nginx.pid gespeichert, wobei der Dateipfad nginx.pid von nginx.conf konfiguriert wird. Der zweite Befehl sendet das Signal QUIT an den alten Masterprozess. Die PID des Prozesses wird in der Datei /var/run/nginx.pid.oldbin gespeichert und anschließend wird der alte Masterprozess beendet. Die Frage ist also, warum die PID des alten Masterprozesses in zwei PID-Dateien vorhanden ist? Tatsächlich hat der alte Masterprozess nach dem Senden des USR2-Signals an den alten Masterprozess die PID umbenannt und die ursprüngliche Datei nginx.pid wurde in nginx.pid.oldbin umbenannt. Auf diese Weise kann der neue Master den Dateinamen nginx.pid verwenden. Führen Sie zuerst den ersten Befehl aus. Das Ergebnis ist wie folgt: Ja, die alten und neuen Master- und Worker-Prozesse koexistieren. Lassen Sie uns den zweiten Befehl ausführen. Das Ergebnis ist wie folgt: Wie Sie sehen, wurden der alte Masterprozess 8527 und seine Arbeitsprozesse alle beendet, sodass nur der neue Masterprozess 12740 übrig blieb. Ich frage mich, warum das manuelle Starten einer neuen Instanz nicht funktioniert, ein Neustart mit einem Signal jedoch schon. Schauen Sie sich zunächst die Nginx-Protokolldatei an: Zusätzlich zum vorherigen Fehlerprotokoll gibt es noch einen Hinweis, der bedeutet, dass Sockets vererbt werden und die fd-Werte 6 und 7 sind. Ich habe dem Protokoll folgend den Nginx-Quellcode durchgesehen und die Funktion nginx.c/ngx_exec_new_binary gefunden. ngx_pid_t ngx_exec_new_binary(ngx_cycle_t *Zyklus, char *const *argv) { ... ctx.Pfad = argv[0]; ctx.name = "neuer Binärprozess"; ctx.argv = argv; n = 2; Umgebung = ngx_set_environment(Zyklus, &n); ... var = ngx_alloc(Größe von (NGINX_VAR) + Zyklus->Listening.Nelts * (NGX_INT32_LEN + 1) + 2, Zyklus->Protokoll); ... p = ngx_cpymem(var, NGINX_VAR "=", Größe von(NGINX_VAR)); ls = Zyklus->Zuhören.elts; für (i = 0; i < Zyklus->listening.nelts; i++) { p = ngx_sprintf(p, "%ud;", ls[i].fd); } *p = "\0"; Umgebung[n++] = var; ... umgebung[n] = NULL; ... ctx.envp = (char *const *) env; ccf = (ngx_core_conf_t *) ngx_get_conf(Zyklus->conf_ctx, ngx_core_module); wenn (ngx_rename_file(ccf->pid.data, ccf->oldpid.data) == NGX_FILE_ERROR) { ... gib NGX_INVALID_PID zurück; } pid = ngx_execute(Zyklus, &ctx); wenn (pid == NGX_INVALID_PID) { wenn (ngx_rename_file(ccf->oldpid.data, ccf->pid.data) == NGX_FILE_ERROR) { ... } } ... pid zurückgeben; } Der Funktionsablauf ist
statisches ngx_int_t ngx_add_inherited_sockets(ngx_cycle_t *Zyklus) { ... geerbt = (u_char *) getenv(NGINX_VAR); wenn (geerbt == NULL) { gib NGX_OK zurück; } wenn (ngx_array_init(&cycle->listening, cycle->pool, 10, Größe von (ngx_listening_t)) != NGX_OK) { gib NGX_ERROR zurück; } für (p = geerbt, v = p; *p; p++) { wenn (*p == ':' || *p == ';') { s = ngx_atoi(v, p - v); ... v = p + 1; ls = ngx_array_push(&cycle->listening); wenn (ls == NULL) { gib NGX_ERROR zurück; } ngx_memzero(ls, Größe von(ngx_listening_t)); ls->fd = (ngx_socket_t) s; } } ... ngx_inherited = 1; gibt ngx_set_inherited_sockets(Zyklus) zurück; } Der Funktionsablauf ist: Analysieren Sie den Wert der Umgebungsvariable NGINX_VAR und holen Sie sich den fd zum Speichern im Array Der fd entsprechende Socket wird auf ngx_inherited gesetzt, um die Informationen dieser Sockets zu speichern. Mit anderen Worten, der neue Server bindet den Abhörport überhaupt nicht neu. Diese fd-Zustände und -Werte werden übernommen, wenn der neue Masterprozess sich aufspaltet. Der neue Masterprozess kann die geerbten Dateideskriptoren abhören und verarbeiten. Der entscheidende Punkt hierbei ist, dass der Dateideskriptor des Abhörsockets über ENV übergeben wird. 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:
|
<<: JS versteht die Zeitzonen GMT und UTC genau
>>: MySQL-Techniken zum schnellen Datenvergleich
Nachfolgend finden Sie den Code zum Erstellen ein...
Linux-Grundkonfiguration Kompilieren und installi...
öffentliche Funktion json_product_list($where, $o...
1. Tcl-Skriptdatei circle.tcl Codekommentare #Leg...
In diesem Artikelbeispiel wird der spezifische Co...
Finden Sie das Problem Ich bin vor kurzem bei der...
Einführung: Als ich mir in letzter Zeit die Frage...
Die unbedeutende flex-basis hat bei der kleinen F...
Die Konfigurationssyntax von Nginx ist flexibel u...
Die Leistung Ihrer Website oder Ihres Dienstes hä...
【1】Kennen Sie die Breite und Höhe des zentrierten...
Problembeschreibung html <iframe id="h5In...
Während dieser Zeit stieß ich bei der Arbeit an e...
Laden Sie die neueste Version von MySQL für Ubunt...
ElementUI implementiert ein Tutorial zum Laden vo...