Retour au blog

Algorithmes de sélection des blocs Server et Location de Nginx : vue d'ensemble

Algorithmes de sélection des blocs Server et Location de Nginx : vue d'ensemble

Introduction

Nginx figure parmi les options de serveur web les plus populaires au monde. Il est capable de gérer avec succès une multitude de connexions clients simultanées. En même temps, il fonctionne comme un serveur de messagerie, web ou de proxy inverse.

Ce guide vise à présenter les méthodes en coulisses qui dirigent la manière dont Nginx traite les requêtes des clients. Nous allons démystifier la conception des blocs server et location de type bloc, ainsi qu'expliquer comment réduire au mieux l'imprévisibilité apparente de la gestion des requêtes.

Tout d'abord, voici un tutoriel complet sur comment installer Nginx sur votre serveur Ubuntu. Maintenant, commençons !

Configuration des blocs avec Nginx

L'approche logique de Nginx consiste à trier les configurations destinées à différents objectifs dans des blocs de contenu distincts et plus logiques. Ceux-ci résident dans une structure hiérarchique. Lorsqu'un client émet une requête, Nginx lance un processus par lequel il détermine lesquels de ces blocs de configuration sont les plus appropriés pour répondre à cette requête. Nous nous concentrerons sur ce processus de décision.

Les principaux blocs dont nous allons parler seront les blocs server et les blocs location . Les blocs server sont un sous-ensemble des configurations établies par Nginx qui définissent quel serveur virtuel sera responsable du traitement d'un type de requête défini. Ils sont le plus souvent basés sur l'adresse IP, le nom de domaine ou le port de la requête entrante. Les administrateurs configurent plusieurs blocs server. Ensuite, ils doivent décider laquelle des connexions doit traiter la requête.

Les blocs location résident à l'intérieur des blocs server. Ce sont eux qui décident comment et quelles ressources vous pouvez exploiter pour gérer les requêtes entrantes vers leur serveur parent particulier. Ce modèle est extrêmement flexible. L'espace URI peut être configuré pour utiliser ces blocs de la manière que l'administrateur juge la meilleure.

Décider quel bloc traitera quelle requête avec Nginx

Nginx permet de définir plusieurs blocs server. Tous fonctionnent comme des serveurs web virtuels différents. Par conséquent, il doit y avoir une méthode qui délimite quel serveur traitera les requêtes entrantes particulières. Cela se fait en trouvant la meilleure correspondance pour le traitement de la requête grâce à un système de vérifications définies.

Nginx traite principalement deux directives de bloc server majeures : listen et server_name.

Trouver les correspondances possibles avec la directive « listen »

La première chose que Nginx évalue est le port et l'adresse IP de la requête. Ensuite, il les fait correspondre à la directive listen de chaque serveur. Cette analyse de la liste des serveurs permet d'isoler uniquement les blocs server qui peuvent résoudre la requête en question.

Généralement, la directive listen définit le port et l'adresse IP auxquels un bloc server particulier sera chargé de répondre. Un bloc server qui ne comporte pas de directive listen reçoit par défaut les paramètres d'écoute 0.0.0.0:80. Si Nginx est exécuté par un utilisateur normal non root, le paramètre listen est défini comme 0.0.0.0:8080. Cela signifie que quelle que soit l'interface, si les requêtes proviennent du port 80, les blocs définis de cette manière y répondront. Cependant, cette valeur par défaut n'a pas un poids important dans le processus de sélection d'un serveur.

Vous pouvez configurer la directive listen pour :

  • Une adresse IP unique qui écoute les requêtes sur le port par défaut (80).
  • Un port unique qui écoute sur n'importe quelle interface sur ce port.
  • Une combinaison de port et d'adresse IP.
  • Un chemin de socket Unix défini (cette option n'a d'implications que lorsque les requêtes transitent par différents serveurs).

Nginx appliquera un ensemble de règles pour décider vers quel bloc server une requête sera envoyée. Les règles dépendent de la configuration particulière de la directive listen. Elles sont les suivantes :

  • Si une directive listen est incomplète, les éléments manquants obtiennent leurs valeurs par défaut. Cela signifie que l'adresse IP et le port seront complétés de force avec des valeurs par défaut afin de traiter la requête.
    • Dans ce cas, un bloc ne contenant aucune directive listen utilisera la valeur par défaut de 0.0.0.0:80.
    • Un bloc auquel il manque un port et qui possède une adresse IP de 111.111.111.111 deviendra 111.111.111.111:80.
    • Lorsqu'il n'y a pas d'adresse IP, un bloc avec le port 8888 acquerra l'adresse IP par défaut à ajouter pour créer 0.0.0.0:8888.
  • Une fois l'adresse IP et le port déterminés, Nginx recherchera ensuite les blocs de serveur proposés comme correspondance pour ce port.
  • S'il ne trouve qu'une seule correspondance spécifique, ce sera le bloc de serveur. S'il y a plusieurs blocs éligibles, Nginx se tournera vers la directive server_name pour cibler plus précisément le bloc de serveur exact en question.

Nginx ne recourra à l'évaluation de la directive server_name que s'il n'a pas trouvé le bloc de serveur avec le niveau de spécificité exact de la directive listen. Si example.com est sur le port 80, avec une IP de 192.168.1.10, le premier bloc de cet exemple sera toujours celui qui traitera la requête. C'est le cas quel que soit le contenu de la directive server_name :

Nginx Server

S'il y a plus d'un bloc de service qualifié avec une correspondance de spécificité, alors la directive server_name sera prise en considération.

Trouver des correspondances possibles avec la directive ‘Server_Name’

Si les directives listen sont également spécifiques, Nginx vérifiera l’en-tête ‘Host’ de la requête. Il s'agit d'une valeur qui contiendra initialement l'IP du domaine que le client cherchait à atteindre. Nginx utilisera la directive server_name à l'intérieur de chaque candidat de bloc de serveur encore qualifié. Il effectue ces évaluations sur la base d'une formule. Elle est la suivante :

  • La première tentative de Nginx sera d'identifier un bloc avec un server_name correspondant exactement à la valeur de l'en-tête ‘Host’ dans la requête. S'il le trouve, le bloc contenant la correspondance exacte sera celui qui servira la requête. S'il trouve plusieurs blocs, il choisira le premier de la liste.
  • S'il n'y a pas de correspondance exacte, Nginx tentera alors d'utiliser server_name pour trouver le bloc de serveur qui correspond à l'aide de *, un caractère générique au début du nom du bloc de serveur dans la configuration. En trouver un avec cette méthode signifie que le bloc de serveur a été déterminé. S'il trouve plus d'une correspondance, la correspondance la plus longue sera celle qui traitera la requête.
  • Sans caractère générique correspondant, Nginx tentera de trouver un bloc de serveur avec un caractère générique de fin correspondant. En d'autres termes, il s'agira d'un nom de serveur avec un * à la fin dans la configuration. Si l'un d'eux est trouvé, il est utilisé pour la requête. Tandis que, si vous en trouvez plusieurs, Nginx utilisera à nouveau la correspondance la plus longue.
  • Dans le cas où il n'y aurait toujours pas de correspondance après les deux tentatives de caractères génériques, Nginx évaluera les blocs de serveur qui définissent le server_name en utilisant des expressions régulières (désignées par un ~ devant le nom). La première instance de server_name avec une expression correspondant à celle de l'en-tête ‘Host’ sera considérée comme le bloc de serveur pour le traitement de la requête.
  • Si à ce stade il n'y a toujours pas de correspondance, Nginx utilisera le bloc de serveur par défaut pour cette combinaison de port et d'adresse IP.

Chaque combinaison de port/adresse IP aura un bloc de serveur désigné. Il sera utilisé si les règles de détermination du bloc de serveur approprié pour le traitement de la requête sont infructueuses. Ce sera le premier bloc de la configuration contenant une option default_server dans la directive listen (cela remplacerait l'algorithme initialement trouvé). Chaque combinaison d'adresse IP/port ne peut avoir, au plus, qu'un seul paramètre default_server.

Exemples de sélection de blocs de serveur

Si le server_name défini correspond exactement à la valeur de l'en-tête ‘Host’, ce sera le bloc de serveur sélectionné pour le traitement de la requête. L'exemple suivant montre un en-tête ‘Host’ de la requête désigné par « host1.example.com ». Dans ce cas, il sélectionnera le deuxième serveur :

Nginx Server

Sans correspondance exacte, Nginx vérifiera si le server_name avec un caractère générique existe. Sinon, la correspondance la plus longue commençant par un caractère générique sera sélectionnée. Dans ce qui suit, « www.example.org » figure sur l'en-tête « Host ». Cela signifie qu'il choisira le deuxième bloc :

server screenshot

Sans correspondance commençant par le caractère générique, Nginx passe à une vérification du caractère générique de fin. La correspondance la plus longue se terminant par le caractère générique sera sélectionnée pour le traitement de la requête. Dans ce cas, l'en-tête « Host » est « www.example.com », il choisira donc le troisième bloc de serveur :

Nginx Server

S'il n'y a toujours pas de correspondance, Nginx tentera de faire correspondre les directives server_name à l'aide d'expressions régulières. La première de ces expressions est sélectionnée pour le traitement de la requête. Si le « Host » est « www.example.com », le deuxième bloc de serveur sera choisi pour répondre à la requête :

Nginx Server

Si aucune correspondance n'est trouvée, la requête sera dirigée vers la combinaison d'adresse IP et de port configurée avec le serveur par défaut correspondant.

Correspondance des blocs Location

Nginx doit également établir un algorithme par lequel il décidera quel bloc location sur le serveur sera responsable de répondre à une requête.

Syntaxe des blocs Location

Avant d'expliquer comment Nginx décide de désigner le bloc location qui traitera les requêtes, nous allons passer en revue la syntaxe des définitions de blocs location. Comme indiqué précédemment, les blocs location résident dans des blocs server (et d'autres blocs location). Leur but est de prendre des décisions sur la façon de traiter l'URI de la requête. L'URI est la partie de la requête qui vient après l'adresse IP et le port ou le nom de domaine de la requête.

Les blocs location ressemblent généralement à ceci :

Syntax for Location Blocks

Nginx comparera l'URI de la requête à location_match. La présence ou l'absence du modificateur ci-dessus dictera la manière dont Nginx tentera de faire correspondre les blocs. Selon le modificateur, les blocs location seront interprétés selon les règles suivantes :

  • Aucun modificateur : Sans aucun modificateur, la location sera interprétée comme une correspondance de préfixe. Cela signifie que la location fournie sera comparée au début de l'URI de la requête pour déterminer une correspondance correcte.
  • =: Le signe égal signifie que ce bloc sera considéré comme une correspondance tant que l'URI de la requête correspond exactement à la location fournie.
  • ~: Le modificateur tilde indique que la correspondance du bloc location sera sensible à la casse.
  • ~*: La combinaison d'un tilde et d'un astérisque indique que le bloc location sera insensible à la casse lors de la recherche d'une correspondance.
  • ^~: Si le modificateur tilde est précédé d'un accent circonflexe, la correspondance par expression régulière n'aura pas lieu tant que ce bloc est choisi comme la meilleure correspondance hors expression régulière.

Exemples de syntaxe de bloc Location

Pour présenter un exemple de correspondance de préfixe, le bloc location sera sélectionné pour répondre à un URI de requête sous la forme de /site, /site/page1/index.html ou /site/index/html :

location site

Pour les besoins de cette démonstration de correspondance d'URI requise, le bloc sera toujours utilisé pour répondre aux requêtes d'URI sous la forme de /page1, et non à l'URI de requête /page1/index.html. S'il s'agit du bloc sélectionné et qu'il répond à la requête à l'aide d'une page d'index, le gestionnaire réel de la requête sera redirigé en interne vers un autre emplacement :

Nginx Server

Par exemple, pour un emplacement qui doit être interprété avec une expression sensible à la casse, le bloc suivant ne pourrait pas traiter les requêtes pour /FLOWER.PNG. Cependant, il traitera les requêtes pour /tortoise.jpg :

Nginx Server and Location Block Selection Algorithms: Overview

Ensuite, observez un bloc qui permettrait une correspondance insensible à la casse similaire à celui ci-dessus. Dans ce cas, le bloc pourrait traiter à la fois //tortoise.jpg et /FLOWER.PNG :

location

La dernière variante est celle dans laquelle un bloc empêcherait la correspondance par expression régulière d'avoir lieu si la détermination est telle qu'il s'agit de la correspondance optimale hors expression régulière. Celui-ci peut traiter les requêtes pour /costumes/ninja.html :

Nginx Server and Location Block Selection Algorithms: Overview

Pour être précis, les modificateurs dictent la manière dont les blocs location sont déterminés. Cela ne nous dit pas, cependant, ce que Nginx utilise comme algorithme de prise de décision pour identifier le bloc location auquel une requête doit être envoyée. Abordons cela ensuite.

Choisir le bloc Location qui traitera les requêtes par Nginx

La méthode par laquelle Nginx choisit la directive location qui traite une requête est similaire à la façon dont les blocs serveurs sont sélectionnés. En d'autres termes, il détermine l'emplacement optimal pour chaque requête en exécutant un processus. Afin de configurer Nginx de manière précise et appropriée, il est impératif de comprendre ce processus.

En gardant à l'esprit les déclarations de location abordées précédemment, Nginx utilise de la même manière les contextes de location potentiels en vérifiant l'éligibilité de chaque location en lui comparant l'URI d'une requête donnée. Pour ce faire, il applique l'algorithme suivant :

  • Tout d'abord, Nginx vérifie tous les types de location qui n'incluent pas d'expression régulière. Il le fait en recherchant toutes les correspondances de préfixe basées sur la location. Pour ce faire, il compare la location à l'URI complète de la requête.
  • Nginx commence par rechercher une correspondance exacte. Dès qu'un bloc location utilisant le modificateur = est identifié, il est comparé à l'URI de la requête. Si les deux correspondent exactement, le bloc location est sélectionné pour traiter la requête sur-le-champ.
  • S'il n'y a pas de locations correspondant exactement à la comparaison du modificateur =, Nginx procède à l'évaluation des préfixes non exacts. Une fois qu'il a déterminé la location avec le préfixe le plus long correspondant à l'URI de la requête, il effectue les évaluations suivantes :
    • Si la location avec la correspondance de préfixe la plus longue utilise le modificateur ^~, cette location sera immédiatement choisie.
    • Si la location avec le préfixe le plus long n'utilise pas le modificateur ^~, la correspondance est temporairement conservée par Nginx pour permettre de déplacer le focus de la recherche.
  • Une fois la correspondance de location au préfixe le plus long trouvée et stockée, Nginx passe à l'évaluation des locations avec expressions régulières. Celles-ci incluent les correspondances sensibles et insensibles à la casse. Si la location au préfixe correspondant le plus long contient des locations régulières, Nginx réorganisera la liste pour les placer près du début de la liste des locations. La première expression de la liste réorganisée qui correspond à l'URI d'une requête sera la location choisie pour traiter la requête.
  • Si aucune expression régulière n'est trouvée pour satisfaire l'URI de la requête, la location stockée précédemment sera choisie pour traiter la requête.

Par défaut, Nginx donne la priorité aux correspondances d'expressions régulières par rapport aux correspondances de préfixes préférentielles. Il évalue cependant d'abord les locations de préfixe, de sorte que l'administrateur puisse passer outre cette tendance à l'aide des modificateurs = et ^~.

Un autre point important à retenir est que, alors que les locations de préfixe sont généralement basées sur la correspondance la plus spécifique et la plus longue trouvée, la vérification d'une expression régulière s'arrête dès que la première correspondance est identifiée. Cela signifie que le positionnement au sein de la configuration a de réelles implications pour les locations d'expressions régulières.

Un dernier point à aborder est que les correspondances d'expressions régulières au sein de la correspondance avec le préfixe le plus long vont essentiellement couper la file d'attente lors des évaluations de location de Nginx. Celles-ci seront positionnées en haut de la liste et évaluées avant les autres expressions régulières.

Quand le passage à d'autres locations se produit-il lors de l'évaluation des blocs location ?

Généralement, une fois qu'une requête est évaluée et qu'un bloc location pour la traiter est sélectionné, elle sera entièrement traitée dans ce contexte. Cela signifie que seules les directives héritées et les locations sélectionnées déterminent le traitement de la requête, sans aucune intervention des blocs location frères.

Bien qu'il s'agisse d'une directive générale qui permet une conception prévisible des blocs location, certaines directives au sein de la location peuvent parfois déclencher également une nouvelle recherche. En d'autres termes, la règle du « seul bloc location » comporte quelques exceptions. Ces exceptions peuvent ne pas correspondre aux attentes des blocs location. Par conséquent, elles risquent de ne pas traiter la requête comme prévu.

Ces redirections internes peuvent finir par se manifester en raison de certaines directives, notamment :

  • index
  • rewrite
  • error_page
  • try_files

Si vous utilisez la directive index, cela entraînera toujours une redirection interne lors du traitement de la requête. Bien que la recherche de correspondances d'emplacement mette généralement fin à l'exécution de l'algorithme pour accélérer le processus de sélection, si la correspondance d'emplacement trouvée est un répertoire, la requête sera probablement redirigée vers un autre emplacement pour être formellement traitée.

Par exemple, le premier emplacement suivant correspond à un URI de requête /exact. Cependant, pour traiter la requête, la directive index dont hérite le bloc d'emplacement redirige la requête vers un bloc secondaire :

index

Pour ce scénario, si l'exécution doit rester au sein du bloc principal, un autre schéma devra traiter la requête vers le répertoire. Une façon de procéder consiste à configurer un index non valide pour le bloc en question, et à activer l'auto-index à la place :

location exact

Bien que cette méthode puisse fonctionner dans quelques cas, elle n'est pas globalement applicable en pratique dans la plupart des contextes. Une correspondance exacte de répertoire peut être utile pour les situations où la requête doit être réécrite. Cela déclenchera une toute nouvelle recherche d'emplacement.

Une autre directive qui peut être utilisée pour réévaluer l'emplacement de traitement est la directive try_files. Elle indique à Nginx de vérifier spécifiquement si un ensemble nommé de fichiers ou de répertoires existe, le dernier critère de recherche étant l'URI vers lequel Nginx doit rediriger en interne.

Considérons la configuration suivante :

root var

S'il y a une requête pour /blahblah, le premier emplacement la recevra. Le fait de ne pas trouver le fichier blahblah dans le répertoire /var/www/main déclenchera une recherche de suivi pour blahblah.html. Ensuite, il recherchera un sous-répertoire nommé blahblah dans le répertoire /var/www/main. Si toutes ces vérifications échouent, il redirigera vers /fallback/index.html. Cela déclenchera une autre recherche d'emplacement qu'un autre bloc d'emplacement récupérera. Ensuite, il traitera le fichier /var/www/another/fallback/index.html.

Une autre directive qui entraîne une redirection vers un autre bloc d'emplacement est la directive rewrite. Nginx recherchera un nouvel emplacement correspondant en fonction du résultat de la directive rewrite lorsque le paramètre last est utilisé. Si le dernier exemple est modifié pour inclure maintenant cette directive rewrite, il devient évident que la requête peut être redirigée vers un autre emplacement sans que la directive try_files ne soit implémentée :

root var ww main

Pour cet exemple, la requête pour /rewrite/hello sera initialement traitée par le premier emplacement. Après avoir été réécrite en /hello, une recherche d'emplacement secondaire sera déclenchée. Elle correspondra au premier emplacement. Elle sera traitée par la directive try_file, revenant potentiellement à /fallback/index.html si elle ne donne aucun résultat.

Si une requête est faite pour /rewrite/fallback/hello, cependant, une correspondance avec le premier bloc sera trouvée. Ainsi, la réécriture sera traitée à nouveau, mais donnera cette fois /fallback/hello comme résultat. La requête sera traitée sur un autre bloc d'emplacement.

Des situations similaires se produisent lorsque vous utilisez la directive return pour envoyer des codes d'état 301 ou 302. La seule différence est qu'une nouvelle requête en résulte, et se manifeste par une redirection très évidente. De même, cela peut se produire avec la directive rewrite lorsque vous appliquez les drapeaux permanent ou redirect.

Une autre directive qui peut conduire à des redirections internes similaires à celle de try_again est la directive error_page. Vous pouvez l'utiliser lorsque vous rencontrez des codes d'erreur particuliers lors du traitement. Lorsqu'une directive try_files est définie, la directive error_page ne sera probablement jamais exécutée. C’est parce que cette directive gérera l'intégralité du cycle de vie de la requête.

Considérons l'exemple suivant :

root screenshot

Dans ce cas, chaque requête sera traitée par le premier bloc servant des fichiers à partir de /var/www/main. Cela ne s'applique pas aux requêtes qui commencent par /another. Mais si un fichier n'était pas trouvé, une redirection interne serait initiée vers /another/whoops/html. Cela mènera à une autre recherche d'emplacement. À son tour, cela dirigera la requête vers un bloc secondaire, ce fichier étant traité à partir de /var/www/another/whoops.html.

Comme on peut le constater, la compréhension des situations dans lesquelles Nginx déclenchera une nouvelle recherche de location peut aider à mieux prédire le comportement du système lors du traitement des requêtes.

Conclusion

Le travail des administrateurs devient immensément plus simple lorsqu'ils comprennent les méthodes par lesquelles Nginx traite les requêtes des clients. Cela permet aux administrateurs de déterminer vers quel bloc server la requête sera dirigée. Ils peuvent également déterminer le bloc location qui sera sélectionné en fonction de l'URI de la requête. Dans l'ensemble, cela donne également aux administrateurs la possibilité de tracer les contextes appliqués par Nginx lors du traitement de chaque requête.

Enfin, vous pouvez jeter un œil aux autres tutoriels sur notre blog consacrés à Nginx. Ils vous aideront à mieux tirer parti de l'un des serveurs web les plus populaires au monde :

Bonne informatique !

author

Manpreet Singh

Auteur · CloudSigma

Preslav Dobrev est un designer créatif chez CloudSigma, axé sur une identité commerciale cohérente à travers des canaux marketing traditionnels et innovants. Il excelle à fusionner la vision artistique avec le marketing stratégique pour créer des récits de marque percutants.

Commentaires

Aucun commentaire pour l'instant. Soyez le premier.