← Back to notes

NGINX: Request
Processing Phases


Теория

Полный список фаз

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

Ссылки

NGINX: Request Processing Phases | Aleksandr Suprun