Heim  >  Artikel  >  Betrieb und Instandhaltung  >  So verwenden Sie das Upstream-Modul in Nginx

So verwenden Sie das Upstream-Modul in Nginx

WBOY
WBOYnach vorne
2023-05-13 08:40:121687Durchsuche

Einführung in das Upstream-Modul

  • Nginx-Module sind im Allgemeinen in drei Kategorien unterteilt: Handler, Filter und Upstream. In den vorherigen Kapiteln haben die Leser bereits etwas über Handler und Filter gelernt. Mit diesen beiden Modultypen kann Nginx problemlos jede eigenständige Arbeit erledigen.

  • Das Upstream-Modul ermöglicht es Nginx, die Einschränkungen einer einzelnen Maschine zu überwinden und den Empfang, die Verarbeitung und die Weiterleitung von Netzwerkdaten abzuschließen.

  • Die Datenweiterleitungsfunktion bietet Nginx horizontale Verarbeitungsfunktionen auf einer einzelnen Maschine, wodurch Nginx von der Einschränkung befreit wird, nur eine einzige Funktion für Endknoten bereitzustellen, und ihm die Funktionen des Teilens, Kapselns und Integrierens gleichzeitig ermöglicht Netzwerkanwendungsebene.

  • Datenweiterleitung ist eine Schlüsselkomponente der Fähigkeit von Nginx, eine Netzwerkanwendung zu erstellen. Aus Gründen der Entwicklungskosten werden Schlüsselkomponenten einer Netzwerkanwendung natürlich zunächst häufig mit höheren Programmiersprachen entwickelt. Wenn das System jedoch eine bestimmte Größe erreicht und mehr Wert auf Leistung gelegt wird, müssen die in Hochsprachen entwickelten Komponenten strukturell geändert werden, um die erforderlichen Leistungsziele zu erreichen.

In Bezug auf die Änderungskosten zeigt das Upstream-Modul von Nginx derzeit seine Vorteile, da es von Natur aus schnell ist. Abgesehen davon macht die hierarchische und lose Kopplung, die das Konfigurationssystem von nginx bietet, das System auf einem relativ hohen Niveau skalierbar.

Upstream-Modulschnittstelle

Im Wesentlichen gehört Upstream zum Handler, generiert jedoch keinen eigenen Inhalt, sondern erhält Inhalte durch Anforderung des Back-End-Servers, daher wird er Upstream (Upstream) genannt. Der gesamte Prozess des Anforderns und Erhaltens von Antwortinhalten wurde in Nginx gekapselt, sodass das Upstream-Modul nur mehrere Rückruffunktionen entwickeln muss, um bestimmte Aufgaben wie das Erstellen von Anforderungen und das Parsen von Antworten abzuschließen.

Rückruffunktionen des Upstream-Moduls sind wie folgt aufgeführt:

Erzeugt einen an den Backend-Server gesendeten Anforderungspuffer (Pufferkette), der bei der Initialisierung des Upstreams verwendet wird Wenn ein Backend-Server ausfällt, versucht Nginx einen anderen Backend-Server. Nachdem Nginx einen neuen Server ausgewählt hat, ruft es zunächst diese Funktion auf, um den Arbeitsstatus des Upstream-Moduls neu zu initialisieren, und verbindet dann den Upstream erneut, um den vom Back-End-Server zurückgegebenen Informationsheader zu verarbeiten. Der sogenannte Header wird durch das Protokoll für die Kommunikation mit dem Upstream-Server angegeben, z. B. durch den Header-Teil des HTTP-Protokolls oder durch den Antwortstatus-Teil des Memcached-Protokolls, der aufgerufen wird, wenn der Client ihn angibt die Anfrage stellen. Es ist nicht erforderlich, die Funktion zum Schließen der Back-End-Serververbindung in der Funktion zu implementieren. Das System führt die Schritte zum Schließen der Verbindung im Allgemeinen nicht aus wird aufgerufen, nachdem die Anfrage mit dem Back-End-Server normal abgeschlossen wurde. Diese Funktion führt wie abort_request im Allgemeinen keine spezifische Arbeit aus. Input_Filter verarbeitet den vom Backend-Server zurückgegebenen Antworttext. Der Standard-Eingabefilter von Nginx kapselt den empfangenen Inhalt in eine Pufferkette ngx_chain. Diese Kette befindet sich im Upstream-Zeigerfeld out_bufs, sodass Entwickler diesen Zeiger verwenden können, um die vom Back-End-Server außerhalb des Moduls zurückgegebenen Textdaten abzurufen. Das memcached-Modul implementiert seinen eigenen input_filter. Dieses Modul wird später im Detail analysiert. Initialisieren Sie den Eingabefilterkontext. Der standardmäßige input_filter_init von nginx gibt direkt zurück
Funktionsname Beschreibung
create_request create_request
reinit_request
process_header
finalize_request
input_filter_init

Memcached-Modulanalyse

  • Memcache ist ein leistungsstarkes verteiltes Cache-System, das weit verbreitet ist. Memcache definiert ein privates Kommunikationsprotokoll, sodass auf Memcache nicht über HTTP-Anfragen zugegriffen werden kann. Da das Protokoll selbst jedoch einfach und effizient ist und Memcache weit verbreitet ist, bieten die meisten modernen Entwicklungssprachen und -plattformen Memcache-Unterstützung, um Entwicklern die Verwendung von Memcache zu erleichtern.

  • nginx stellt das Modul ngx_http_memcached bereit, das die Funktion zum Lesen von Daten aus dem Memcache bereitstellt, jedoch nicht die Funktion zum Schreiben von Daten in den Memcache.

Das Upstream-Modul verwendet die Zugriffsmethode des Handler-Moduls.

Gleichzeitig folgt das Design des Befehlssystems des Upstream-Moduls auch den Grundregeln des Handler-Moduls: Das Modul wird erst nach der Konfiguration des Moduls ausgeführt.

Was ist also das Besondere am Upstream-Modul? Das ist die Verarbeitungsfunktion des Upstream-Moduls. Die von der Verarbeitungsfunktion des Upstream-Moduls ausgeführten Vorgänge umfassen einen festen Prozess: (Nehmen Sie das Memcached-Modul in der Verarbeitungsfunktion ngx_http_memcached_handler von Memcached)

Erstellen Sie die Upstream-Datenstruktur :

ngx_http_upstream_t            *u;
if (ngx_http_upstream_create(r) != NGX_OK) {
    return NGX_HTTP_INTERNAL_SERVER_ERROR;
}
u = r->upstream;

Legen Sie das Modul-Tag und das Schema fest. Das Schema wird jetzt nur für Protokolle verwendet und Tags werden für die buf_chain-Verwaltung verwendet:

ngx_str_set(&u->schema, "memcached://");
u->output.tag = (ngx_buf_tag_t) &ngx_http_memcached_module;

Legen Sie die Datenstruktur der Back-End-Serverliste des Upstreams fest:

mlcf = ngx_http_get_module_loc_conf(r, ngx_http_memcached_module);
u->conf = &mlcf->upstream;

Setzen Sie die Upstream-Rückruffunktion fest:

u->create_request = ngx_http_memcached_create_request;
u->reinit_request = ngx_http_memcached_reinit_request;
u->process_header = ngx_http_memcached_process_header;
u->abort_request = ngx_http_memcached_abort_request;
u->finalize_request = ngx_http_memcached_finalize_request;
   
u->input_filter_init = ngx_http_memcached_filter_init;
u->input_filter = ngx_http_memcached_filter;

Erstellen und richten Sie die Datenstruktur der Upstream-Umgebung ein:

ctx = ngx_palloc(r->pool, sizeof(ngx_http_memcached_ctx_t));
if (ctx == NULL) {
    return NGX_HTTP_INTERNAL_SERVER_ERROR;
}
ctx->request = r;

ngx_http_set_ctx(r, ctx, ngx_http_memcached_module);

u->input_filter_ctx = ctx;

Schließen Sie die Upstream-Initialisierung ab und beenden Sie die Arbeit:

r->main->count++;
ngx_http_upstream_init(r);
return NGX_DONE;

Dies gilt für jedes Upstream-Modul, so einfach wie Memcached, so komplex wie Proxy und FastCGI.
Der größte Unterschied zwischen verschiedenen Upstream-Modulen in diesen 6 Schritten wird in den Schritten 2, 3, 4 und 5 sichtbar.

Schritte 2 und 4 sind leicht zu verstehen. Die von verschiedenen Modulen gesetzten Flags und die verwendeten Rückruffunktionen sind definitiv unterschiedlich. Auch Schritt 5 ist nicht schwer zu verstehen.

Nur Schritt 3 ist etwas verwirrend. Verschiedene Module verfolgen sehr unterschiedliche Strategien beim Abrufen der Backend-Serverliste. Einige sind so einfach und klar wie Memcached, andere sind so logisch komplex wie Proxy.

Schritt 6 ist normalerweise zwischen verschiedenen Modulen konsistent. Erhöhen Sie die Anzahl um 1 und geben Sie NGX_DONE zurück.
nginx stößt auf diese Situation, obwohl es davon ausgeht, dass die Verarbeitung der aktuellen Anforderung beendet ist, gibt jedoch weder die von der Anforderung verwendeten Speicherressourcen frei, noch wird die Verbindung mit dem Client geschlossen.
Der Grund, warum dies erforderlich ist, liegt darin, dass Nginx eine Eins-zu-Eins-Beziehung zwischen Upstream-Anfragen und Client-Anfragen eingerichtet hat. Bei der anschließenden Verwendung von ngx_event_pipe zum Zurücksenden der Upstream-Antwort an den Client werden diese Daten mit Client-Informationen ebenfalls verwendet. Struktur.
Upstream-Anfragen und Client-Anfragen eins zu eins binden. Dieses Design hat Vor- und Nachteile. Der Vorteil besteht darin, dass es die Modulentwicklung vereinfacht und es Ihnen ermöglicht, sich auf die Modullogik zu konzentrieren. Die Nachteile liegen jedoch ebenso auf der Hand. Ein Eins-zu-eins-Design kann den Anforderungen komplexer Logik oft nicht gerecht werden.

Rückruffunktion: (immer noch die Verarbeitungsfunktion des Memcached-Moduls als Beispiel)

  • ngx_http_memcached_create_request: Es ist sehr einfach, einen Schlüssel entsprechend dem festgelegten Inhalt zu generieren und dann einen „get $ key“ zu generieren. request und füge es in r ->upstream->In request_bufs ein.

  • ngx_http_memcached_reinit_request: Keine Initialisierung erforderlich.

  • ngx_http_memcached_abort_request: Keine zusätzliche Aktion erforderlich.

  • ngx_http_memcached_finalize_request: Keine zusätzliche Aktion erforderlich.

  • ngx_http_memcached_process_header: Die Geschäftsfokusfunktion des Moduls. Die Header-Informationen des Memcache-Protokolls sind als erste Textzeile definiert. Der Code lautet wie folgt:

#define LF     (u_char) '\n'
for (p = u->buffer.pos; p < u->buffer.last; p++) {
    if (*p == LF) {
        goto found;
    }
}

Wenn das LF-Zeichen („n’] nicht in den Daten gefunden wird, die in den Puffer eingelesen wurden Die Funktion gibt NGX_AGAIN zurück, was darauf hinweist, dass der Header nicht vollständig gelesen wurde und mit dem Lesen der Daten fortgefahren werden muss. Nginx ruft diese Funktion erneut auf, nachdem neue Daten empfangen wurden.

nginx verwendet bei der Verarbeitung der Antwortheader des Backend-Servers nur einen Cache. Alle Daten befinden sich in diesem Cache, sodass beim Parsen der Header-Informationen nicht berücksichtigt werden muss, dass sich die Header-Informationen über mehrere Caches erstrecken. Wenn der Header zu groß ist und nicht in diesem Cache gespeichert werden kann, gibt Nginx eine Fehlermeldung an den Client zurück und zeichnet ein Fehlerprotokoll auf, das darauf hinweist, dass der Cache nicht groß genug ist.

Die wichtige Aufgabe von ngx_http_memcached_process_header besteht darin, den vom Backend-Server zurückgegebenen Status in den an den Client zurückgegebenen Status zu übersetzen. Beispiel:

u->headers_in.content_length_n = ngx_atoof(start, p - start);
···
u->headers_in.status_n = 200;
u->state->status = 200;
···
u->headers_in.status_n = 404;
u->state->status = 404;

u->state wird zur Berechnung von Upstream-bezogenen Variablen verwendet. Beispielsweise wird u->state->status verwendet, um den Wert der Variablen „upstream_status“ zu berechnen. u->headers_in wird als Statuscode in der Antwort an den Client zurückgegeben. Und u->headers_in.content_length_n legt die Länge der an den Client zurückgegebenen Antwort fest.

In dieser Funktion müssen Sie den Lesezeiger pos nach der Verarbeitung der Header-Informationen nach hinten verschieben, da diese Daten sonst auch in den Hauptteil der an den Client zurückgegebenen Antwort kopiert werden, was zu einem falschen Hauptinhalt führt. Die Funktion

ngx_http_memcached_process_header schließt die korrekte Verarbeitung des Antwortheaders ab und sollte NGX_OK zurückgeben. Wenn NGX_AGAIN zurückgegeben wird, bedeutet dies, dass nicht die vollständigen Daten gelesen wurden und die Daten weiterhin vom Backend-Server gelesen werden müssen. Die Rückgabe von NGX_DECLINED ist bedeutungslos. Jeder andere Rückgabewert wird als Fehlerstatus betrachtet und nginx beendet die Upstream-Anfrage und gibt eine Fehlermeldung zurück.

ngx_http_memcached_filter_init: Korrigieren Sie die vom Backend-Server empfangene Inhaltslänge. Denn dieser Teil der Länge wird bei der Verarbeitung des Headers nicht addiert.

ngx_http_memcached_filter:
memcached-Modul ist ein seltenes Modul mit einer Rückruffunktion zur Textverarbeitung.
Da das zwischengespeicherte Modul das CRLF „END“ CRLF am Ende des Textes filtern muss, hat es eine eigene Filter-Callback-Funktion implementiert.

Die eigentliche Bedeutung der Textverarbeitung besteht darin, den gültigen Inhalt des vom Back-End-Server empfangenen Texts in ngx_chain_t zu kapseln und ihn am Ende von u->out_bufs hinzuzufügen.

nginx kopiert keine Daten, sondern erstellt die Datenstruktur ngx_buf_t, um auf diese Datenspeicherbereiche zu verweisen, und organisiert diese Puffer dann nach ngx_chain_t. Diese Implementierung vermeidet eine groß angelegte Speicherverlagerung und ist einer der Gründe, warum Nginx effizient ist.

Das obige ist der detaillierte Inhalt vonSo verwenden Sie das Upstream-Modul in Nginx. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!

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