Объяснение блоков location в Nginx: маршрутизация веб-трафика
Блоки location в Nginx — основа эффективной маршрутизации веб-трафика. Это подробное руководство разбирает пять различных модификаторов сопоставления (префикс, точное совпадение, самый длинный префикс, регулярные выражения) и объясняет строгий порядок обработки, которому следует Nginx. Узнайте, как точно маршрутизировать статические ресурсы, проксировать API-вызовы и реализовывать правила безопасности с помощью практических примеров конфигурации. Освоение блоков location — ключ к точному управлению трафиком, обеспечивающему быструю производительность сервера и надежное управление конфигурацией.
Объяснение блоков location в Nginx: маршрутизация веб-трафика
Блоки location в Nginx определяют, что происходит после того, как запрос попадает в правильный блок server. Именно благодаря им /static/app.css может быть отдан с диска, /api/users — проксирован на приложение, а /.git/config — заблокирован до того, как утечет что-то чувствительное.
Большинство ошибок с блоками location — это не синтаксические ошибки. Это ошибки приоритета. Регулярное выражение перехватывает запрос, который, как вы ожидали, должен обработать префиксный блок. Путь root добавляет больше URI, чем вы думали. proxy_pass с завершающим слешем перезаписывает URI вышестоящего сервера иначе, чем та же директива без него. Примеры ниже сосредоточены именно на этих реальных точках отказа.
Роль и анатомия блока location
Блок location определяет, как Nginx должен отвечать на запросы на основе URI запроса. Эти блоки всегда вложены в блок server.
Когда клиент отправляет запрос (например, GET /images/logo.png), Nginx проверяет URI запроса на соответствие всем определенным блокам location в прослушивающем блоке server, чтобы определить соответствующую обработку, такую как отдача файла, перенаправление клиента или проксирование запроса на сервер приложения.
Базовый синтаксис
Синтаксис требует модификатор (или его отсутствие), за которым следует шаблон (URI):
location [модификатор] [шаблон] {
# Директивы конфигурации (например, root, index, proxy_pass)
}
Понимание типов сопоставления location (модификаторы)
Nginx предлагает небольшой набор стилей сопоставления location. Выбор влияет как на точность маршрутизации, так и на объем работы, которую Nginx выполняет перед выбором обработчика.
1. Префиксное сопоставление (без модификатора)
Это тип сопоставления по умолчанию. Nginx ищет самую длинную начальную строку, которая соответствует URI запроса.
| Модификатор | Пример | Поведение | Наилучший вариант использования |
|---|---|---|---|
| (нет) | location /blog/ |
Соответствует URI, начинающимся с /blog/ (например, /blog/post/1). |
Общего назначения, определение больших разделов сайта. |
Пример:
location /docs/ {
root /var/www/html/public;
# Если URI равен /docs/manual.pdf, Nginx ищет /var/www/html/public/docs/manual.pdf
}
2. Точное совпадение (=)
Этот модификатор принудительно задает точное совпадение между URI и шаблоном. При совпадении Nginx немедленно прекращает поиск других location. Это самый быстрый тип сопоставления.
| Модификатор | Пример | Поведение | Наилучший вариант использования |
|---|---|---|---|
= |
location = /favicon.ico |
Соответствует только URI /favicon.ico точно. |
Обработка конкретных, часто запрашиваемых файлов или страниц по умолчанию. |
3. Самый длинный префикс, не regex (^~)
Это специализированное префиксное совпадение. Если Nginx находит самое длинное префиксное совпадение с помощью ^~, он немедленно прекращает проверку любых блоков location с регулярными выражениями (regex), фактически переопределяя их.
| Модификатор | Пример | Поведение | Наилучший вариант использования |
|---|---|---|---|
^~ |
location ^~ /assets/ |
Соответствует URI, начинающимся с /assets/, и предотвращает проверку более медленных совпадений regex. |
Быстрая отдача статических ресурсов и обеспечение предсказуемой обработки каталогов с ресурсами. |
4. Регулярное выражение с учетом регистра (~)
Использует Perl-совместимые регулярные выражения (PCRE) для сопоставления. Это мощно, но медленнее, чем префиксные совпадения. Выигрывает первый совпавший блок regex.
| Модификатор | Пример | Поведение | Наилучший вариант использования |
|---|---|---|---|
~ |
location ~ \.php$ |
Соответствует любому URI, заканчивающемуся на .php. |
Обработка определенных типов файлов (например, передача PHP-скриптов в PHP-FPM). |
5. Регулярное выражение без учета регистра (~*)
Идентично ~, но сопоставление игнорирует регистр URI.
| Модификатор | Пример | Поведение | Наилучший вариант использования |
|---|---|---|---|
~* |
`location ~* .(jpg | gif | png)$` |
Критический порядок обработки location
Понимание порядка, в котором Nginx обрабатывает блоки location, жизненно важно для избежания неожиданного поведения. Nginx не просто читает файлы конфигурации сверху вниз. Он использует строгую иерархию:
- Точное совпадение (
=): Nginx сначала проверяет все блоки точного совпадения. Если совпадение найдено, обработка немедленно прекращается, и запрос обрабатывается этим блоком. - Кандидат с самым длинным префиксом: Nginx находит самое длинное совпадающее префиксное расположение, включая обычные префиксные location и location с
^~. - Пропуск regex для
^~: Если это лучшее префиксное совпадение использует^~, Nginx использует его и пропускает проверки regex. - Регулярные выражения (
~и~*): Если лучший префикс не был^~, Nginx проверяет location regex в том порядке, в котором они появляются в файле конфигурации. Выигрывает первый совпавший блок regex. - Самое длинное стандартное префиксное совпадение: Если ни одно совпадение regex не выиграло, Nginx использует уже найденного кандидата с самым длинным префиксом. Во многих конфигурациях
location /является окончательным запасным вариантом.
Вот почему ^~ /static/ распространен. Без ^~ более позднее regex, такое как location ~* \.(css|js)$, все еще может выиграть для /static/app.css. Иногда это нормально. Иногда это обходит заголовки кэша, корневой путь или правила доступа, которые вы ожидали для всего каталога /static/.
Практические сценарии конфигурации
1. Приоритизация статических ресурсов для производительности
Чтобы гарантировать, что Nginx обслуживает статические файлы напрямую и быстро, предотвращая более медленные проверки regex и ненужную обработку сервером приложений, используйте модификатор ^~.
server {
listen 80;
server_name myapp.com;
# 1. Точное совпадение для главной страницы (наивысший приоритет)
location = / {
proxy_pass http://backend_app_server;
}
# 2. Быстрая обработка статических ресурсов, минуя проверки regex
location ^~ /static/ {
root /var/www/site;
expires 30d;
}
# 3. Регулярное выражение для распространенных медиафайлов
location ~* \.(gif|ico|css|js)$ {
root /var/www/site;
expires 7d;
}
# 4. Запасной вариант для всех остальных динамических запросов
location / {
proxy_pass http://backend_app_server;
}
}
2. Маршрутизация и проксирование API-трафика
При использовании Nginx в качестве обратного прокси блоки location направляют трафик на правильный вышестоящий сервер приложений.
location /api/v1/ {
# Обеспечивает, чтобы Nginx учитывал настройки соединения клиента
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
# Направляет весь трафик, начинающийся с /api/v1/, на серверную службу
proxy_pass http://api_backend_service/v1/;
# С URI в proxy_pass Nginx заменяет совпадающий префикс.
# /api/v1/users становится /v1/users на вышестоящем сервере.
}
Это поведение завершающего слеша стоит протестировать. Эти два примера различаются:
location /api/ {
proxy_pass http://api_backend;
}
location /api/ {
proxy_pass http://api_backend/;
}
Первая форма передает исходный URI, включая /api/..., на вышестоящий сервер. Вторая форма заменяет совпавший префикс /api/ на /. Если ваш вышестоящий сервер внезапно начинает возвращать 404 после небольшого редактирования конфигурации, проверьте это, прежде чем винить приложение.
3. Защита конфиденциальных каталогов
Блоки location можно использовать для запрета внешнего доступа к конфиденциальным внутренним каталогам, таким как файлы конфигурации или скрытые каталоги, например .git.
# Запретить доступ к файлам, начинающимся с точки (скрытые файлы)
location ~ /\.(ht|svn|git) {
deny all;
return 404; # Возвращать 404 вместо 403, чтобы не раскрывать их существование
}
# Запретить доступ к определенным каталогам конфигурации
location /app/config/ {
deny all;
}
Для скрытых файлов многие команды используют более широкое правило запрета:
location ~ /\.(?!well-known/) {
deny all;
return 404;
}
Исключение оставляет /.well-known/ доступным для таких вещей, как вызовы ACME HTTP-01 для сертификатов, при этом блокируя большинство dot-файлов. Тщательно тестируйте это, если ваш сайт обслуживает другие легитимные пути, начинающиеся с точки.
Предупреждение безопасности: Использование
aliasvs.rootПри настройке путей к файлам в блоке location помните о разнице между
rootиalias.
root: Добавляет полный URI запроса к определенному пути. (например,location /images/+root /data/приводит к/data/images/filename.jpg)alias: Заменяет совпавшую часть URI на определенный путь. Это часто необходимо, когда блок location использует regex или должен отрезать часть пути перед отдачей файла. (например,location /static/+alias /opt/app/files/приводит к/opt/app/files/filename.jpg)
4. Обработка завершающих слешей и перенаправлений
Часто желательно обеспечить согласованную структуру URL, например, гарантировать, что каталоги всегда заканчиваются завершающим слешем (/).
# Принудительно добавлять завершающий слеш для путей каталогов, если он отсутствует
location ~* /[a-z0-9\-_]+$ {
# Если URI соответствует файлу, Nginx попытается его отдать. Если нет, обрабатывать как каталог.
# Проверить, соответствует ли запрошенный URI каталогу на диске:
if (-d $request_filename) {
return 301 $uri/;
}
}
Хороший способ отладки маршрутизации location
Когда запрос попадает не туда, сведите проблему к одному URL и одному блоку server. Запустите nginx -T, чтобы увидеть полную скомпилированную конфигурацию, включая включенные файлы, затем найдите каждый location, который может соответствовать этому URI. Уделите особое внимание блокам regex, потому что их порядок в файле имеет значение.
Для статических файлов подтвердите путь файловой системы, который Nginx построит из root или alias. Для проксируемых запросов подтвердите, включает ли proxy_pass часть URI после имени вышестоящего сервера. Затем перезагружайте только после того, как nginx -t пройдет успешно.
Блоки location предсказуемы, как только вы усвоите правила приоритета, но они не прощают ошибок, когда конфигурация разрастается путем копирования и вставки. Используйте точные совпадения для маленьких горячих путей, ^~ для каталогов, которые должны обходить обработку regex, regex только там, где сопоставление с шаблоном действительно необходимо, и простой location / в качестве четкого запасного варианта.