Лекция
Привет, Вы узнаете о том , что такое алгоритмы выбора блоков server, Разберем основные их виды и особенности использования. Еще будет много подробных примеров и описаний. Для того чтобы лучше понимать что такое алгоритмы выбора блоков server, location в nginx , настоятельно рекомендую прочитать все из категории Выполнение скриптов на стороне сервера PHP (LAMP) NodeJS (Backend) .
Nginx – один из популярнейших веб-серверов в мире. Он может обрабатывать высокие нагрузки и большое количество одновременных подключений. Также Nginx можно использовать в качестве балансировщика, почтового сервера или обратного прокси.
Данный мануал расскажет, как Nginx обрабатывает клиентские запросы. Понимание этого механизма поможет вам оптимизировать обработку запросов.
Nginx логически делит конфигурации, предназначенные для обслуживания различного контента, на блоки, которые собираются в иерархическую структуру. Обработку каждого запроса клиента Nginx начинает с определения необходимых блоков конфигурации. Этот процесс принятия решений будет центральной темой данного мануала.
Основные блоки, которые мы обсудим, называются server и location.
Блок server – это подмножество конфигурации Nginx, которая определяет виртуальный сервер, используемый для обработки запросов определенного типа. Администраторы часто настраивают несколько блоков server, где каждый блок обрабатывает соединения на основе запрошенного домена, порта и IP-адреса.
Блок location находится в блоке server и используется для того, чтобы Nginx мог обрабатывать запросы для разных ресурсов и URI родительского сервера. С помощью этого блока администратор может разделить пространство URI требуемым образом. Это чрезвычайно гибкая модель.
Nginx позволяет определять несколько блоков server, которые функционируют как отдельные экземпляры виртуальных веб-серверов. Потому Nginx необходима процедура определения того, какой из этих блоков будет использоваться для обработки запроса.
Для этого Nginx применяет определенную систему проверок, которые используются для поиска наилучшего совпадения. Основные директивы блока server, которые помогают Nginx определить требуемый блок, — это listen и server_name.
Сначала Nginx смотрит на IP-адрес и порт запроса. Он сопоставляет эти значения с директивой listen каждого блока server и создает список блоков, которые могут обслужить запрос.
Директива listen обычно определяет IP-адрес и порт блока server. По умолчанию любой блок server, в котором нет директивы listen, получает параметры 0.0.0.0:80 (или 0.0.0.0:8080, если Nginx запускается обычным пользователем без полномочий root). Это позволяет таким блокам отвечать на запросы на любом интерфейсе по порту 80. Но это стандартное значение не имеет большого веса в процессе выбора блока.
Директива listen может указывать:
Последний вариант, как правило, используется только при передаче запросов между разными серверами.
Сначала Nginx попробует выбрать блок на основе директивы listen, используя следующие правила:
Важно понимать, что Nginx будет оценивать директиву server_name только тогда, когда ему нужно выбрать один блок из списка блоков, отобранных по директиве listen. Например, если домен example.com размещен на порту 80 по адресу 192.168.1.10, запрос на example.com всегда будет обслуживаться первым блоком в пример ниже, несмотря на директиву server_name во втором блоке.
server {
listen 192.168.1.10;
. . .
}
server {
listen 80;
server_name example.com;
. . .
}
Если же Nginx отобрал несколько блоков с одинаковым уровнем специфичности, далее он проверит директиву server_name.
Для дальнейшей оценки запросов, имеющих одинаковые определения директивы listen, Nginx проверяет заголовок Host запроса. Это значение содержит домен или IP-адрес, который запрашивает клиент.
Nginx ищет наилучшее совпадение этого значения в директиве server_name каждого блока, прошедшего предыдущий этап отбора. Nginx оценивает эту директиву по этой формуле:
Для каждой комбинации IP-адреса и порта существует блок server по умолчанию, который используется в случае, если веб-сервер не смог найти другой блок. Об этом говорит сайт https://intellect.icu . Как правило, это либо первый блок в конфигурации, либо блок, который содержит параметр default_server как часть директивы listen (она переопределяет алгоритм поиска первого совпадения). Для каждой комбинации IP-адреса и порта может быть только одно объявление default_server.
Если в конфигурации есть блок с директивой server_name, значение которой полностью совпадает с заголовком Host запроса, запрос передается на обработку этому блоку.
К примеру, если заголовок Host запроса – host1.example.com, веб-сервер выберет для его обслуживания второй блок server:
server {
listen 80;
server_name *.example.com;
. . .
}
server {
listen 80;
server_name host1.example.com;
. . .
}
Если Nginx не находит точных совпадений, он будет искать блок, в котором server_name начинается со специального символа. Если Nginx найдет несколько совпадений, для обслуживания запроса будет использоваться наиболее точное из них. Например, если в запросе указан заголовок Host www.example.org, Nginx выберет второй блок:
server {
listen 80;
server_name www.example.*;
. . .
}
server {
listen 80;
server_name *.example.org;
. . .
}
server {
listen 80;
server_name *.org;
. . .
}
Если найти блок по специальному символу в начале директивы не удалось, Nginx будет искать блок, значение server_name которого заканчивается специальным символом. Если он найдет несколько совпадений, он использует наиболее точное из них. К примеру, для обработки запроса с заголовком Host www.example.com веб-сервер использует третий блок server:
server {
listen 80;
server_name host1.example.com;
. . .
}
server {
listen 80;
server_name example.com;
. . .
}
server {
listen 80;
server_name www.example.*;
. . .
}
Если найти блок по специальному символу не получилось, Nginx будет искать директивы server_name, которые содержат регулярные выражения. Для обработки запроса будет использоваться первый блок, чье регулярное выражение в директиве совпало с заголовком запроса.
К примеру, для обслуживания запроса с заголовком Host www.example.com веб-сервер выберет второй блок server:
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$;
. . .
}
Если ни один из механизмов поиска не дал результатов, веб-сервер применит блок server по умолчанию.
Похожий алгоритм Nginx использует для поиска блока location.
Для начала следует ознакомиться с синтаксисом блока location. Блоки location находятся внутри блоков server (или других блоков location) и используются для определения способа обработки URI запроса (той части запроса, которая идет после имени домена или IP-адреса/порта).
Как правило, блок location имеет такой вид:
location optional_modifier location_match {
. . .
}
location_match в приведенном выше примере указывает, что Nginx должен проверить URI запроса. Наличие или отсутствие модификатора в приведенном выше примере влияет на то, как Nginx будет искать блок location.
Существуют такие модификаторы блоков location:
В качестве примера поиска по префиксу можно использовать следующий блок location для ответа на запросы URI (/site, /site/page1/index.html, или /site/index.html).
location /site {
. . .
}
Ниже вы найдете пример точного совпадения URI. Такой блок всегда будет использоваться для обслуживания URI
/page1. Он не будет отвечать на URI запроса /page1/index.html. Имейте в виду, что если выбран этот блок и запрос обслуживается индексной страницей, произойдет внутреннее перенаправление в другой блок location, который будет фактическим обработчиком запроса.
location = /page1 {
. . .
}
Интерпретация блока location как регулярного выражения с учетом регистра происходит в следующем примере. Этот блок будет использован для обработки запросов для /tortoise.jpg, но не для /FLOWER.PNG:
location ~ \.(jpe?g|png|gif|ico)$ {
. . .
}
В следующем примере происходит интерпретация блока location как регулярного выражения без учета регистра. Такой блок сможет обработать запросы и для /tortoise.jpg, и для /FLOWER.PNG.
location ~* \.(jpe?g|png|gif|ico)$ {
. . .
}
Следующий блок отключит поиск по регулярному выражению, если он выбран как наилучшее совпадение без регулярных выражений. Он может обрабатывать запросы для /costumes/ninja.html:
location ^~ /costumes {
. . .
}
Как видите, модификаторы указывают, как следует интерпретировать блок location. Тем не менее, это не определяет алгоритм, который Nginx использует, чтобы решить, какому блоку location отправить запрос.
Nginx выбирает блок location аналогично тому, как он выбирает блок server. Он запускает процесс, который определяет лучший блок location для конкретного запроса. Понимание этого процесса является важнейшим требованием для надежной и точной настройки Nginx.
Имея в виду типы объявлений, которые мы рассмотрели выше, Nginx оценивает возможные контексты location путем сравнения URI запроса с каждым из местоположений. Он делает это, используя следующий алгоритм:
Важно понимать, что по умолчанию Nginx будет обслуживать регулярные выражения, отдавая предпочтение совпадениям по префиксам. Однако сначала он оценивает префиксные location-ы, позволяя администратору переопределять это поведение, указав location-ы с помощью модификаторов = и ^~.
Также важно отметить, что, хотя префиксные location-ы обычно выбираются на основе префикса максимальной длины (наиболее точного совпадения), Nginx перестанет оценивать регулярные выражения при обнаружении первого подходящего location-а. Это означает, что расположение в конфигурации блоков location с регулярными выражениями имеет огромное значение.
Теперь нужно разобраться, в каких случаях оценка блоков location переходит к другим location-ам.
В целом, с того момента, как блок location выбран для обслуживания запроса, запрос обрабатывается целиком в этом контексте. Только выбранный блок location и унаследованные директивы определяют, как обрабатывается запрос, а соседние блоки location не могут вмешиваться в этот процесс.
Это общее правило, которое позволит вам спроектировать блоки location предсказуемым образом. Но при этом важно понимать, что бывают случаи, когда определенные директивы запускают новый поиск location-а внутри выбранного блока location. Исключения из правила могут привести к появлению непредсказуемых результатов.
Вот некоторые из директив, которые могут стать причиной такого поведения:
Директива index всегда приводит ко внутреннему перенаправлению, если она используется для обработки запроса. Точные совпадения location-а часто используются для ускорения процесса выбора, потому что это немедленно прекратит выполнение алгоритма. Однако если точное соответствие location-а будет каталогом, есть вероятность, что для фактической обработки запрос будет перенаправлен в другое место.
В этом примере первый location совпадает с URI запроса /exact, но директива index, унаследованная блоком, для обработки запроса инициирует внутреннее перенаправление ко второму блоку:
index index.html;
location = /exact {
. . .
}
location / {
. . .
}
Если вы хотите, чтобы в приведенном выше случае запрос обрабатывался первым блоком, вам придется придумать другой метод попадания запроса в каталог. Например, вы можете установить для этого блока неправильный index и включить autoindex:
location = /exact {
index nothing_will_match;
autoindex on;
}
location / {
. . .
}
Это один из способов предотвратить перенаправление запроса из первого контекста, но он, вероятно, не подходит для большинства конфигураций. В основном точное совпадение в каталогах может быть полезно для таких операций, как переписывание запроса (что также приводит к новому поиску блока location).
Еще один случай, в котором может начаться новый поиск location-а – это использование директивы try_files. Эта директива говорит Nginx проверить наличие именованного набора файлов или каталогов. Последним параметром может быть URI, на который Nginx сделает внутреннее перенаправление.
Рассмотрим такую конфигурацию:
root /var/www/main;
location / {
try_files $uri $uri.html $uri/ /fallback/index.html;
}
location /fallback {
root /var/www/another;
}
Если в приведенном выше примере запрос сделан для /blahblah, сначала получит запрос первый location. Он попытается найти файл с именем blahblah в каталоге /var/www/main. Если он не сможет найти его, он будет искать файл с именем blahblah.html. Затем он попытается узнать, есть ли в каталоге /var/www/main каталог blahblah/. Если все эти попытки не принесут результатов, запрос будет перенаправлен на /fallback/index.html. Это вызовет новый поиск location-а, и запрос перейдет второму блоку. Он обслужит файл /var/www/another/fallback/index.html.
Также на поиск блоков влияет директива rewrite. Обрабатывая rewrite без параметров или с параметром last, Nginx будет искать новый блок location на основе результатов перезаписи.
Например, если изменить последний пример и добавить в него перезапись, вы увидите, что запрос иногда передается непосредственно второму блоку location, не полагаясь на директиву try_files:
root /var/www/main;
location / {
rewrite ^/rewriteme/(.*)$ /$1 last;
try_files $uri $uri.html $uri/ /fallback/index.html;
}
location /fallback {
root /var/www/another;
}
В приведенном выше примере запрос /rewriteme/hello будет сначала обрабатываться первым блоком location. Он будет переписан в /hello, и веб-сервер будет искать location. В этом случае он снова будет соответствовать первому location-у и обрабатываться директивой try_files (возможно, используя внутреннее перенаправление, чтобы вернуться к /fallback/index.html, если ничего не было найдено).
Однако если запрос сделан для /rewriteme/fallback/hello, первый блок снова будет отвечать запросу. При этом снова применяется перезапись, на этот раз в результате получится /fallback/hello. Затем запрос будет обслуживаться вторым блоком.
Похожая ситуация возникает с директивой return при отправке кодов состояния 301 или 302. Разница в этом случае заключается в том, что она приводит к совершенно новому запросу извне переадресации. Такая же ситуация может возникнуть с директивой rewrite при использовании флагов redirect или permanent.
Директива error_page может привести к внутреннему перенаправлению аналогично тому, как это делает try_files. Эта директива используется для определения действий, которые выполняются при обнаружении определенных кодов состояния. Эти действия, вероятно, никогда не будут выполнены, если установлена директива try_files, так как эта директива обрабатывает весь жизненный цикл запроса.
Рассмотрим такой пример:
root /var/www/main;
location / {
error_page 404 /another/whoops.html;
}
location /another {
root /var/www;
}
Каждый запрос (кроме тех, которые начинаются с /another) будет обрабатываться первым блоком, который будет обслуживать файлы из каталога /var/www/main. Однако если файл не найден (статус 404), произойдет внутреннее перенаправление на /another/whoops.html, что приведет к новому поиску блока location, который в конечном итоге окончится вторым блоком. Этот блок будет обслуживать файл /var/www/another/whoops.html.
Как видите, понимание условий, при которых Nginx запускает новый поиск блока location, может помочь предсказать поведение веб-сервера при выполнении запросов.
Анализ данных, представленных в статье про алгоритмы выбора блоков server, подтверждает эффективность применения современных технологий для обеспечения инновационного развития и улучшения качества жизни в различных сферах. Надеюсь, что теперь ты понял что такое алгоритмы выбора блоков server, location в nginx и для чего все это нужно, а если не понял, или есть замечания, то не стесняйся, пиши или спрашивай в комментариях, с удовольствием отвечу. Для того чтобы глубже понять настоятельно рекомендую изучить всю информацию из категории Выполнение скриптов на стороне сервера PHP (LAMP) NodeJS (Backend)
Комментарии
Оставить комментарий
Выполнение скриптов на стороне сервера PHP (LAMP) NodeJS (Backend)
Термины: Выполнение скриптов на стороне сервера PHP (LAMP) NodeJS (Backend)