Теория
Полный список фаз
HTTP-запрос проходит через 11 фаз phase engine (в порядке исполнения):
precontent появилась в 1.13.4 (раньше — try_files-фаза). post_access существует для согласования решений нескольких access-проверок.
Phase engine = state machine
Phase engine — конечный автомат, двигающий request по цепочке хендлеров.
Коды возврата:
NGX_OK— переход к следующей фазе;NGX_DECLINED— следующий handler в текущей фазе;NGX_AGAIN/NGX_DONE— пауза обработки (возврат в event loop), продолжение позже.
Internal redirect
При internal redirect (rewrite ... last, try_files, error_page) меняется URI/локация. NGINX заново делает location lookup и повторно запускает фазовый проход для нового URI.
В rewrite-модуле цикл internal redirect ограничен 10 итерациями, после чего возвращается 500.
NGX_AGAIN
NGX_AGAIN означает: операция не завершена, нужно подождать I/O. Worker не блокируется — управление уходит в event loop, обработка продолжится по новому событию.
Что нужно уметь объяснить
Почему redirect требует нового location lookup?
После redirect у запроса другой URI. Старый location может больше не подходить, NGINX обязан заново выбрать самый подходящий location и продолжить фазы.
Что произойдёт, если handler вернёт NGX_DECLINED?
Не ошибка и не финальный ответ. «Этот handler не обработал запрос» — phase engine передаст request следующему handler в текущей фазе либо пойдёт дальше по фазам.
Чем rewrite отличается от content handler?
rewriteменяет маршрут запроса (URI/правила), не генерирует тело;content handlerформирует ответ клиенту (файл, proxy, fastcgi, return).
Практика
1. rewrite + proxy_pass
server {
listen 8080;
server_name _;
location /api/ {
rewrite ^/api/v1/(.*)$ /backend/$1 break;
proxy_pass http://127.0.0.1:18080;
}
}
rewrite ... break меняет URI внутри текущего location, запрос уходит в proxy_pass.
2. Internal redirect
server {
listen 8080;
server_name _;
location /old/ {
rewrite ^/old/(.*)$ /new/$1 last;
}
location /new/ {
proxy_pass http://127.0.0.1:18080;
}
}
last вызывает internal redirect, NGINX заново делает location lookup для /new/....
3. Debug log
error_log /var/log/nginx/error.log debug;
Для debug-уровня NGINX должен быть собран с --with-debug.
nginx -t && sudo nginx -s reload
sudo tail -f /var/log/nginx/error.log
curl -i http://127.0.0.1:8080/api/v1/test
curl -i http://127.0.0.1:8080/old/test