Grundlegendes zu Nginx Server- und Standortblockauswahlalgorithmen

Einführung

Nginx ist einer der beliebtesten Webserver der Welt. Es kann mit vielen gleichzeitigen Clientverbindungen erfolgreich hohe Lasten bewältigen und problemlos als Webserver, Mailserver oder Reverseproxyserver fungieren.

In diesem Handbuch werden einige Details im Hintergrund erläutert, die bestimmen, wie Nginx Clientanforderungen verarbeitet. Das Verstehen dieser Ideen kann dazu beitragen, das Rätselraten beim Entwerfen von Server- und Standortblöcken zu erleichtern und die Verarbeitung von Anforderungen weniger unvorhersehbar erscheinen zu lassen.

Nginx-Blockkonfigurationen

Nginx unterteilt die Konfigurationen, die unterschiedliche Inhalte bedienen sollen, logisch in Blöcke, die in einer hierarchischen Struktur vorliegen. Bei jeder Client-Anfrage beginnt Nginx mit der Ermittlung, welche Konfigurationsblöcke zur Bearbeitung der Anfrage verwendet werden sollen. Über diesen Entscheidungsprozess werden wir in diesem Handbuch sprechen.

Die Hauptblöcke, die wir diskutieren werden, sind derserver-Block und derlocation-Block.

Ein Serverblock ist eine Teilmenge der Nginx-Konfiguration, die einen virtuellen Server definiert, der zum Verarbeiten von Anforderungen eines definierten Typs verwendet wird. Administratoren konfigurieren häufig mehrere Serverblöcke und entscheiden anhand des angeforderten Domänennamens, Ports und der IP-Adresse, welcher Block welche Verbindung verarbeiten soll.

Ein Standortblock befindet sich innerhalb eines Serverblocks und wird verwendet, um zu definieren, wie Nginx Anforderungen für verschiedene Ressourcen und URIs für den übergeordneten Server behandeln soll. Der URI-Bereich kann mit diesen Blöcken nach Belieben des Administrators unterteilt werden. Es ist ein extrem flexibles Modell.

Wie Nginx entscheidet, welcher Serverblock eine Anfrage verarbeitet

Da der Administrator mit Nginx mehrere Serverblöcke definieren kann, die als separate virtuelle Webserverinstanzen fungieren, muss festgelegt werden, welche dieser Serverblöcke zur Erfüllung einer Anforderung verwendet werden.

Dies geschieht durch ein definiertes Überprüfungssystem, mit dem die bestmögliche Übereinstimmung ermittelt wird. Die Hauptserverblockanweisungen, mit denen sich Nginx während dieses Prozesses befasst, sind die Direktivelistenund die Direktiveserver_name.

Analysieren der "Listen" -Richtlinie, um mögliche Übereinstimmungen zu finden

Zunächst überprüft Nginx die IP-Adresse und den Port der Anforderung. Dies wird mit der Anweisunglistenjedes Servers verglichen, um eine Liste der Serverblöcke zu erstellen, die möglicherweise die Anforderung auflösen können.

Die Anweisunglistendefiniert normalerweise, auf welche IP-Adresse und welchen Port der Serverblock reagiert. Standardmäßig erhält jeder Serverblock, der keinelisten-Direktive enthält, die Listen-Parameter0.0.0.0:80 (oder0.0.0.0:8080, wenn Nginx von einem normalen Benutzer ohne Rootberechtigung ausgeführt wird). Dies ermöglicht diesen Blöcken, auf Anforderungen an einer Schnittstelle an Port 80 zu antworten, aber dieser Standardwert hat innerhalb des Serverauswahlprozesses keine große Bedeutung.

Die Direktivelistenkann wie folgt festgelegt werden:

  • Eine Kombination aus IP-Adresse und Port.

  • Eine einzelne IP-Adresse, die dann den Standardport 80 überwacht.

  • Ein einzelner Port, der jede Schnittstelle an diesem Port überwacht.

  • Der Pfad zu einem Unix-Socket.

Die letzte Option hat im Allgemeinen nur Auswirkungen auf die Weitergabe von Anforderungen zwischen verschiedenen Servern.

Bei dem Versuch zu bestimmen, an welchen Serverblock eine Anfrage gesendet werden soll, versucht Nginx zunächst, anhand der Spezifität derlisten-Richtlinie anhand der folgenden Regeln zu entscheiden:

  • Nginx übersetzt alle "unvollständigen"listen-Richtlinien, indem fehlende Werte durch ihre Standardwerte ersetzt werden, sodass jeder Block anhand seiner IP-Adresse und seines Ports ausgewertet werden kann. Einige Beispiele für diese Übersetzungen sind:

    • Ein Block ohnelisten-Direktive verwendet den Wert0.0.0.0:80.

    • Ein Block, der auf eine IP-Adresse111.111.111.111 ohne Port gesetzt ist, wird zu111.111.111.111:80

    • Ein Block, der auf Port8888 ohne IP-Adresse gesetzt ist, wird zu0.0.0.0:8888

  • Nginx versucht dann, basierend auf der IP-Adresse und dem Port eine Liste der Serverblöcke zu sammeln, die der Anforderung am besten entsprechen. Dies bedeutet, dass ein Block, der funktional0.0.0.0 als IP-Adresse verwendet (um mit einer beliebigen Schnittstelle übereinzustimmen), nicht ausgewählt wird, wenn übereinstimmende Blöcke vorhanden sind, in denen eine bestimmte IP-Adresse aufgeführt ist. In jedem Fall muss der Port genau übereinstimmen.

  • Wenn nur eine Übereinstimmung vorliegt, wird dieser Serverblock verwendet, um die Anforderung zu bedienen. Wenn mehrere Serverblöcke mit derselben Spezifitätsübereinstimmung vorhanden sind, beginnt Nginx mit der Auswertung derserver_name-Richtlinie jedes Serverblocks.

Es ist wichtig zu verstehen, dass Nginx dieserver_name-Richtlinie nur dann auswertet, wenn zwischen Serverblöcken unterschieden werden muss, die der gleichen Spezifität in derlisten-Richtlinie entsprechen. Wenn beispielsweiseexample.com auf Port80 von192.168.1.10 gehostet wird, wird eine Anforderung fürexample.com in diesem Beispiel trotzserver_nameimmer vom ersten Block bedient ) s Direktive im zweiten Block.

server {
    listen 192.168.1.10;

    . . .

}

server {
    listen 80;
    server_name example.com;

    . . .

}

Für den Fall, dass mehr als ein Serverblock mit gleicher Spezifität übereinstimmt, besteht der nächste Schritt darin, die Direktiveserver_namezu überprüfen.

Analysieren der Anweisung "Servername", um eine Übereinstimmung auszuwählen

Um Anforderungen mit gleich spezifischenlisten-Richtlinien weiter auszuwerten, überprüft Nginx den Host-Header der Anforderung. Dieser Wert enthält die Domäne oder IP-Adresse, die der Client tatsächlich erreichen wollte.

Nginx versucht, die beste Übereinstimmung für den gefundenen Wert zu finden, indem es die Direktiveserver_namein jedem der Serverblöcke betrachtet, die noch Auswahlkandidaten sind. Nginx bewertet diese anhand der folgenden Formel:

  • Nginx versucht zunächst, einen Serverblock mit einemserver_name zu finden, der dem Wert im "Host" -Header der Anforderungexactly entspricht. Wenn dies gefunden wird, wird der zugehörige Block verwendet, um die Anforderung zu bedienen. Wenn mehrere exakte Übereinstimmungen gefunden werden, wird diefirst verwendet.

  • Wenn keine genaue Übereinstimmung gefunden wird, versucht Nginx, einen Serverblock mit einemserver_name zu finden, der mit einem führenden Platzhalter übereinstimmt (angezeigt durch ein* am Anfang des Namens in der Konfiguration). Wenn einer gefunden wird, wird dieser Block verwendet, um die Anfrage zu bedienen. Wenn mehrere Übereinstimmungen gefunden werden, wird die Übereinstimmung vonlongestverwendet, um die Anforderung zu bedienen.

  • Wenn mit einem führenden Platzhalter keine Übereinstimmung gefunden wird, sucht Nginx nach einem Serverblock mit einemserver_name, der mit einem nachfolgenden Platzhalter übereinstimmt (angezeigt durch einen Servernamen, der in der Konfiguration mit* endet). Wenn einer gefunden wird, wird dieser Block verwendet, um die Anfrage zu bedienen. Wenn mehrere Übereinstimmungen gefunden werden, wird die Übereinstimmung vonlongestverwendet, um die Anforderung zu bedienen.

  • Wenn mit einem nachgestellten Platzhalter keine Übereinstimmung gefunden wird, wertet Nginx Serverblöcke aus, die dieserver_name mithilfe regulärer Ausdrücke definieren (angezeigt durch~ vor dem Namen). Diefirstserver_name mit einem regulären Ausdruck, der mit dem "Host" -Header übereinstimmt, werden zur Bearbeitung der Anforderung verwendet.

  • Wenn keine Übereinstimmung mit regulären Ausdrücken gefunden wird, wählt Nginx den Standardserverblock für diese IP-Adresse und diesen Port aus.

Jede IP-Adresse / Port-Kombination verfügt über einen Standard-Serverblock, der verwendet wird, wenn mit den oben genannten Methoden keine Vorgehensweise ermittelt werden kann. Bei einer Kombination aus IP-Adresse und Port ist dies entweder der erste Block in der Konfiguration oder der Block, der die Optiondefault_server als Teil der Direktivelisten enthält (die den zuerst gefundenen Algorithmus überschreiben würde). . Pro IP-Adresse / Port-Kombination kann nur einedefault_server-Deklaration vorhanden sein.

Beispiele

Wenn einserver_namedefiniert ist, das genau mit dem Header-Wert "Host" übereinstimmt, wird dieser Serverblock ausgewählt, um die Anforderung zu verarbeiten.

In diesem Beispiel wird der zweite Server ausgewählt, wenn der Header "Host" der Anforderung auf "host1.example.com" gesetzt ist:

server {
    listen 80;
    server_name *.example.com;

    . . .

}

server {
    listen 80;
    server_name host1.example.com;

    . . .

}

Wenn keine genaue Übereinstimmung gefunden wird, prüft Nginx, observer_name mit einem passenden Start-Platzhalter vorhanden sind. Die längste Übereinstimmung, die mit einem Platzhalter beginnt, wird ausgewählt, um die Anforderung zu erfüllen.

In diesem Beispiel würde der zweite Serverblock ausgewählt werden, wenn die Anforderung einen "Host" -Header von "http://www.example.org [www.example.org]" hätte:

server {
    listen 80;
    server_name www.example.*;

    . . .

}

server {
    listen 80;
    server_name *.example.org;

    . . .

}

server {
    listen 80;
    server_name *.org;

    . . .

}

Wenn mit einem Startplatzhalter keine Übereinstimmung gefunden wird, prüft Nginx anhand eines Platzhalters am Ende des Ausdrucks, ob eine Übereinstimmung vorliegt. Zu diesem Zeitpunkt wird die längste Übereinstimmung ausgewählt, die mit einem Platzhalter endet, um die Anforderung zu bedienen.

Wenn für die Anforderung beispielsweise der Header "Host" auf "http://www.example.com [www.example.com]" gesetzt ist, wird der dritte Serverblock ausgewählt:

server {
    listen 80;
    server_name host1.example.com;

    . . .

}

server {
    listen 80;
    server_name example.com;

    . . .

}

server {
    listen 80;
    server_name www.example.*;

    . . .

}

Wenn keine Platzhalterübereinstimmungen gefunden werden können, versucht Nginx, die Anweisungen vonserver_nameabzugleichen, die reguläre Ausdrücke verwenden. Der übereinstimmende reguläre Ausdruck vonfirstwird ausgewählt, um auf die Anfrage zu antworten.

Wenn zum Beispiel der "Host" -Header der Anfrage auf "http://www.example.com [www.example.com]" gesetzt ist, wird der zweite Serverblock ausgewählt, um die Anfrage zu erfüllen:

server {
    listen 80;
    server_name example.com;

    . . .

}

server {
    listen 80;
    server_name ~^(www|host1).*\.example\.com$;

    . . .

}

server {
    listen 80;
    server_name ~^(subdomain|set|www|host1).*\.example\.com$;

    . . .

}

Wenn keiner der oben genannten Schritte die Anforderung erfüllen kann, wird die Anforderung an dendefault-Server weitergeleitet, um die passende IP-Adresse und den passenden Port zu erhalten.

Übereinstimmende Standortblöcke

Ähnlich dem Prozess, den Nginx verwendet, um den Serverblock auszuwählen, der eine Anforderung verarbeitet, verfügt Nginx auch über einen festgelegten Algorithmus, um zu entscheiden, welcher Standortblock auf dem Server für die Verarbeitung von Anforderungen verwendet werden soll.

Standortblock-Syntax

Bevor wir uns damit befassen, wie Nginx entscheidet, welcher Standortblock für die Bearbeitung von Anforderungen verwendet werden soll, gehen wir zunächst einige der in den Standortblockdefinitionen möglicherweise angezeigten Syntaxen durch. Standortblöcke befinden sich innerhalb von Serverblöcken (oder anderen Standortblöcken) und werden verwendet, um zu entscheiden, wie der Anforderungs-URI (der Teil der Anforderung, der nach dem Domänennamen oder der IP-Adresse / dem Port folgt) verarbeitet werden soll.

Ortsblöcke haben im Allgemeinen die folgende Form:

location optional_modifier location_match {

    . . .

}

Daslocation_match oben definiert, gegen was Nginx den Anforderungs-URI prüfen soll. Das Vorhandensein oder Nichtvorhandensein des Modifikators im obigen Beispiel wirkt sich auf die Art und Weise aus, wie der Nginx versucht, mit dem Positionsblock übereinzustimmen. Die folgenden Modifikatoren bewirken, dass der zugehörige Positionsblock wie folgt interpretiert wird:

  • (none): Wenn keine Modifikatoren vorhanden sind, wird der Speicherort alsprefix-Übereinstimmung interpretiert. Dies bedeutet, dass der angegebene Speicherort mit dem Beginn der Anforderungs-URI abgeglichen wird, um eine Übereinstimmung zu ermitteln.

  • =: Wenn ein Gleichheitszeichen verwendet wird, wird dieser Block als Übereinstimmung betrachtet, wenn der Anforderungs-URI genau mit dem angegebenen Ort übereinstimmt.

  • ~: Wenn ein Tilde-Modifikator vorhanden ist, wird dieser Speicherort als Übereinstimmung zwischen regulären Ausdrücken und Groß- und Kleinschreibung interpretiert.

  • ~*: Wenn ein Tilde- und ein Sternchenmodifikator verwendet werden, wird der Positionsblock als Übereinstimmung zwischen regulären Ausdrücken ohne Berücksichtigung der Groß- und Kleinschreibung interpretiert.

  • ^~: Wenn ein Karat- und Tilde-Modifikator vorhanden ist und dieser Block als beste Übereinstimmung mit nicht regulären Ausdrücken ausgewählt ist, findet keine Übereinstimmung mit regulären Ausdrücken statt.

Beispiele zur Demonstration der Location Block-Syntax

Als Beispiel für die Präfixübereinstimmung kann der folgende Standortblock ausgewählt werden, um auf Anforderungs-URIs zu antworten, die wie/site,/site/page1/index.html oder/site/index.html aussehen:

location /site {

    . . .

}

Zur Demonstration der genauen Übereinstimmung der Anforderungs-URI wird dieser Block immer verwendet, um auf eine Anforderungs-URI zu antworten, die wie/page1 aussieht. Es wirdnotverwendet, um auf die Anforderungs-URI von/page1/index.htmlzu antworten. Beachten Sie, dass bei Auswahl dieses Blocks und Erfüllung der Anforderung über eine Indexseite eine interne Weiterleitung an einen anderen Speicherort erfolgt, der der eigentliche Bearbeiter der Anforderung ist:

location = /page1 {

    . . .

}

Als Beispiel für einen Speicherort, der als regulärer Ausdruck mit Groß- und Kleinschreibung interpretiert werden sollte, kann dieser Block verwendet werden, um Anforderungen für/tortoise.jpg, abernot für/FLOWER.PNG zu verarbeiten:

location ~ \.(jpe?g|png|gif|ico)$ {

    . . .

}

Ein Block, der eine Übereinstimmung ohne Berücksichtigung der Groß- und Kleinschreibung ähnlich wie oben ermöglicht, ist unten dargestellt. Hier könnten beide/tortoise.jpgand/FLOWER.PNG von diesem Block behandelt werden:

location ~* \.(jpe?g|png|gif|ico)$ {

    . . .

}

Schließlich würde dieser Block das Auftreten einer Übereinstimmung mit regulären Ausdrücken verhindern, wenn festgestellt wird, dass dies die beste Übereinstimmung mit nicht regulären Ausdrücken ist. Es könnte Anfragen für/costumes/ninja.html verarbeiten:

location ^~ /costumes {

    . . .

}

Wie Sie sehen, geben die Modifikatoren an, wie der Positionsblock interpretiert werden soll. Dies gibt jedochnotan, welchen Algorithmus Nginx verwendet, um zu entscheiden, an welchen Standortblock die Anforderung gesendet werden soll. Wir werden das als nächstes durchgehen.

Wie Nginx den Speicherort für die Bearbeitung von Anfragen auswählt

Nginx wählt den Ort, an dem eine Anfrage bearbeitet wird, ähnlich wie bei der Auswahl eines Serverblocks. Es wird ein Prozess durchlaufen, der den besten Standortblock für eine bestimmte Anforderung ermittelt. Das Verständnis dieses Prozesses ist eine entscheidende Voraussetzung, um Nginx zuverlässig und genau konfigurieren zu können.

Unter Berücksichtigung der oben beschriebenen Arten von Standortdeklarationen bewertet Nginx die möglichen Standortkontexte, indem es den Anforderungs-URI mit jedem der Standorte vergleicht. Hierzu wird der folgende Algorithmus verwendet:

  • Nginx überprüft zunächst alle auf Präfixen basierenden Standortübereinstimmungen (alle Standorttypen, die keinen regulären Ausdruck enthalten). Es überprüft jeden Standort anhand der vollständigen Anforderungs-URI.

  • Zunächst sucht Nginx nach einer genauen Übereinstimmung. Wenn festgestellt wird, dass ein Standortblock mit dem Modifikator=genau mit dem Anforderungs-URI übereinstimmt, wird dieser Standortblock sofort ausgewählt, um die Anforderung zu bedienen.

  • Wenn keine genauen Übereinstimmungsblockübereinstimmungen (mit dem Modifikator=) gefunden werden, fährt Nginx mit der Auswertung nicht exakter Präfixe fort. Es wird der am längsten übereinstimmende Präfixspeicherort für den angegebenen Anforderungs-URI ermittelt, der dann wie folgt ausgewertet wird:

    • Wenn der am längsten übereinstimmende Präfixspeicherort den Modifikator^~hat, beendet Nginx sofort die Suche und wählt diesen Speicherort aus, um die Anforderung zu bearbeiten.

    • Wenn die am längsten übereinstimmende Präfixpositiondoes notden Modifikator^~ verwendet, wird die Übereinstimmung für den Moment von Nginx gespeichert, damit der Fokus der Suche verschoben werden kann.

  • Nachdem die am längsten übereinstimmende Präfixposition bestimmt und gespeichert wurde, wertet Nginx die Positionen für reguläre Ausdrücke aus (Groß- und Kleinschreibung beachten und nicht beachten). Wenn es Positionen mit regulären Ausdrücken gibt, diewithindie am längsten übereinstimmende Präfixposition sind, verschiebt Nginx diese an den Anfang seiner Liste der zu überprüfenden Regex-Positionen. Nginx versucht dann, die Positionen der regulären Ausdrücke nacheinander abzugleichen. Die Position des regulären Ausdrucks vonfirst, die mit dem Anforderungs-URI übereinstimmt, wird sofort ausgewählt, um die Anforderung zu bedienen.

  • Wenn keine Positionen für reguläre Ausdrücke gefunden werden, die mit dem Anforderungs-URI übereinstimmen, wird die zuvor gespeicherte Präfixposition ausgewählt, um die Anforderung zu bedienen.

Es ist wichtig zu verstehen, dass Nginx standardmäßig Übereinstimmungen mit regulären Ausdrücken anstelle von Präfixübereinstimmungen liefert. Es werden jedoch zuerst die Präfixpositionen vonevaluatesangegeben, sodass die Verwaltung diese Tendenz überschreiben kann, indem Positionen mit den Modifikatoren= und^~ angegeben werden.

Es ist auch wichtig zu beachten, dass während Präfixpositionen im Allgemeinen basierend auf der längsten und spezifischsten Übereinstimmung ausgewählt werden, die Auswertung regulärer Ausdrücke gestoppt wird, wenn die erste übereinstimmende Position gefunden wird. Dies bedeutet, dass die Positionierung innerhalb der Konfiguration erhebliche Auswirkungen auf die Positionen der regulären Ausdrücke hat.

Schließlich ist es wichtig zu verstehen, dass reguläre Ausdrücke mitwithinübereinstimmen. Die längste Präfixübereinstimmung überspringt die Linie, wenn Nginx Regex-Positionen auswertet. Diese werden nacheinander ausgewertet, bevor Übereinstimmungen mit anderen regulären Ausdrücken berücksichtigt werden. Maxim Dounin, ein unglaublich hilfreicher Nginx-Entwickler, erklärt diesen Teil des Auswahlalgorithmus inthis post.

Wann springt die Standortblockbewertung zu anderen Standorten?

Im Allgemeinen wird, wenn ein Standortblock ausgewählt wird, um eine Anfrage zu bedienen, die Anfrage von diesem Punkt an vollständig in diesem Kontext behandelt. Nur der ausgewählte Speicherort und die geerbten Anweisungen bestimmen, wie die Anforderung verarbeitet wird, ohne dass geschwisterliche Speicherortblöcke eingreifen.

Obwohl dies eine allgemeine Regel ist, mit der Sie Ihre Standortblöcke vorhersehbar gestalten können, ist es wichtig zu berücksichtigen, dass in bestimmten Situationen eine neue Standortsuche durch bestimmte Anweisungen innerhalb des ausgewählten Standorts ausgelöst wird. Die Ausnahmen von der Regel "Nur ein Standortblock" haben möglicherweise Auswirkungen auf die tatsächliche Zustellung der Anforderung und stimmen möglicherweise nicht mit den Erwartungen überein, die Sie beim Entwerfen Ihrer Standortblöcke hatten.

Einige Anweisungen, die zu dieser Art der internen Weiterleitung führen können, sind:

  • Index

  • try_files

  • umschreiben

  • Fehlerseite

Lassen Sie uns kurz darauf eingehen.

Die Direktiveindexführt immer zu einer internen Umleitung, wenn sie zur Bearbeitung der Anforderung verwendet wird. Genaue Positionsübereinstimmungen werden häufig verwendet, um den Auswahlprozess zu beschleunigen, indem die Ausführung des Algorithmus sofort beendet wird. Wenn Sie jedoch eine genaue Standortübereinstimmung vornehmen, diedirectory beträgt, besteht eine gute Chance, dass die Anforderung zur tatsächlichen Verarbeitung an einen anderen Standort umgeleitet wird.

In diesem Beispiel wird dem ersten Speicherort ein Anforderungs-URI von/exact zugeordnet. Um die Anforderung zu verarbeiten, initiiert die vom Block geerbte Direktiveindex eine interne Umleitung zum zweiten Block:

index index.html;

location = /exact {

    . . .

}

location / {

    . . .

}

Wenn Sie im obigen Fall die Ausführung wirklich benötigen, um im ersten Block zu bleiben, müssen Sie eine andere Methode zur Erfüllung der Anforderung an das Verzeichnis finden. Sie können beispielsweise ein ungültigesindex für diesen Block festlegen undautoindex aktivieren:

location = /exact {
    index nothing_will_match;
    autoindex on;
}

location  / {

    . . .

}

Dies ist eine Möglichkeit, um zu verhindern, dassindex den Kontext wechseln, ist jedoch für die meisten Konfigurationen wahrscheinlich nicht hilfreich. Meist kann eine genaue Übereinstimmung der Verzeichnisse hilfreich sein, wenn Sie beispielsweise die Anforderung neu schreiben (was auch zu einer neuen Standortsuche führt).

Ein anderer Fall, in dem der Verarbeitungsort neu bewertet werden kann, ist die Anweisungtry_files. Diese Anweisung weist Nginx an, zu prüfen, ob eine benannte Gruppe von Dateien oder Verzeichnissen vorhanden ist. Der letzte Parameter kann ein URI sein, zu dem Nginx eine interne Umleitung durchführt.

Betrachten Sie die folgende Konfiguration:

root /var/www/main;
location / {
    try_files $uri $uri.html $uri/ /fallback/index.html;
}

location /fallback {
    root /var/www/another;
}

Wenn im obigen Beispiel eine Anforderung für/blahblah gestellt wird, erhält der erste Standort zunächst die Anforderung. Es wird versucht, eine Datei mit dem Namenblahblah im Verzeichnis/var/www/mainzu finden. Wenn es keine finden kann, sucht es anschließend nach einer Datei mit dem Namenblahblah.html. Anschließend wird versucht, festzustellen, ob sich im Verzeichnis/var/www/mainein Verzeichnis mit dem Namenblahblah/ befindet. Wenn alle diese Versuche fehlschlagen, wird zu/fallback/index.html umgeleitet. Dies löst eine weitere Standortsuche aus, die vom zweiten Standortblock abgefangen wird. Dies dient der Datei/var/www/another/fallback/index.html.

Eine weitere Anweisung, die dazu führen kann, dass ein Standortblock übergeben wird, ist die Anweisungrewrite. Wenn der Parameterlast mit der Direktiverewrite verwendet wird oder wenn überhaupt kein Parameter verwendet wird, sucht Nginx basierend auf den Ergebnissen des Umschreibens nach einem neuen übereinstimmenden Speicherort.

Wenn wir beispielsweise das letzte Beispiel so ändern, dass es ein Umschreiben enthält, können wir sehen, dass die Anforderung manchmal direkt an den zweiten Speicherort übergeben wird, ohne sich auf die Direktivetry_fileszu verlassen:

root /var/www/main;
location / {
    rewrite ^/rewriteme/(.*)$ /$1 last;
    try_files $uri $uri.html $uri/ /fallback/index.html;
}

location /fallback {
    root /var/www/another;
}

Im obigen Beispiel wird eine Anforderung für/rewriteme/hello anfänglich vom ersten Standortblock verarbeitet. Es wird in/hello umgeschrieben und ein Ort wird gesucht. In diesem Fall stimmt es wieder mit dem ersten Speicherort überein und wird wie gewohnt vontry_filesverarbeitet, wobei möglicherweise auf/fallback/index.htmlzurückgesetzt wird, wenn nichts gefunden wird (unter Verwendung der oben beschriebenen internen Umleitung vontry_files) ).

Wenn jedoch eine Anforderung für/rewriteme/fallback/hello gestellt wird, stimmt der erste Block erneut überein. Das Umschreiben wird erneut angewendet, diesmal ergibt sich/fallback/hello. Die Anfrage wird dann aus dem zweiten Standortblock zugestellt.

Eine verwandte Situation tritt bei der Anweisungreturn auf, wenn die Statuscodes301 oder302gesendet werden. Der Unterschied besteht in diesem Fall darin, dass eine völlig neue Anforderung in Form einer von außen sichtbaren Umleitung erfolgt. Dieselbe Situation kann bei der Direktiverewrite auftreten, wenn die Flagsredirect oderpermanent verwendet werden. Diese Standortsuche sollte jedoch nicht unerwartet sein, da von außen sichtbare Umleitungen immer zu einer neuen Anfrage führen.

Die Direktiveerror_page kann zu einer internen Umleitung führen, die der vontry_files ähnelt. Mit dieser Anweisung wird definiert, was passieren soll, wenn bestimmte Statuscodes auftreten. Dies wird wahrscheinlich nie ausgeführt, wenntry_files festgelegt ist, da diese Anweisung den gesamten Lebenszyklus einer Anforderung behandelt.

Betrachten Sie dieses Beispiel:

root /var/www/main;

location / {
    error_page 404 /another/whoops.html;
}

location /another {
    root /var/www;
}

Jede Anforderung (außer denjenigen, die mit/another beginnen) wird vom ersten Block verarbeitet, der Dateien aus/var/www/main bereitstellt. Wenn jedoch keine Datei gefunden wird (Status 404), erfolgt eine interne Umleitung zu/another/whoops.html, was zu einer neuen Standortsuche führt, die schließlich im zweiten Block landet. Diese Datei wird aus/var/www/another/whoops.html bereitgestellt.

Wie Sie sehen, kann das Verständnis der Umstände, unter denen Nginx eine neue Standortsuche auslöst, dazu beitragen, das Verhalten vorherzusagen, das Sie bei Anfragen sehen werden.

Fazit

Wenn Sie wissen, wie Nginx Clientanforderungen verarbeitet, können Sie Ihre Arbeit als Administrator erheblich vereinfachen. Sie können feststellen, welchen Serverblock Nginx basierend auf den jeweiligen Clientanforderungen auswählt. Sie können auch angeben, wie der Standortblock basierend auf der Anforderungs-URI ausgewählt wird. Wenn Sie wissen, wie Nginx verschiedene Blöcke auswählt, können Sie die Kontexte nachverfolgen, die Nginx anwenden wird, um jede Anfrage zu bearbeiten.