Назад | Перейти на главную страницу

Как узнать, какие правила перезаписи nginx применяются к запросу?

Я пытаюсь отладить, почему некоторые правила перезаписи не работают на моем промежуточном сервере, хотя они работают на моей виртуальной машине.

Кажется, что когда я перезапускаю nginx, он вообще не видит моих изменений.

Есть ли способ увидеть фактические загруженные confs в nginx или записать, какие правила перезаписи применяются к входящим запросам?

Есть несколько стратегий, которые вы можете использовать для отладки обработки запросов и ответов nginx.

Ведение журнала с учетом перезаписи

Если вы включите rewrite_log директива в server block, затем перезагрузите конфигурацию nginx, вы получите целую кучу информации (по адресу notice severity) о том, что именно nginx делает с вашим запросом при его перезаписи.

Однако, если вам нужно пойти глубже, вы можете включить отладку на гораздо более широком уровне.

Отладка на уровне виртуального хоста

Установив логирование nginx на debug уровня, вы получите чрезвычайно подробный отчет обо всем, что делает nginx при обработке запросов и ответов. Информации много, но в ней содержится ответ на каждую проблему, с которой вы сталкиваетесь с nginx.

Самый простой способ получить журнал отладки - установить уровень серьезности error_log директива для server блок, который вы хотите диагностировать debug. Замените любое существующее ключевое слово серьезности, которое может быть там, например info или warn. Если конкретный server блок не имеет error_log директиву, вы должны добавить ее (поскольку изменение общесерверного error_log к debug приведет к много шума.

После того, как вы внесли это изменение, вам нужно будет заставить nginx перезагрузить свою конфигурацию (перезапускать не нужно).

Примеры:

Существующий error_log с серьезностью:

Измените это:

server {
  server_name foo.example.com;
  error_log /var/log/nginx/foo.example.com.error_log info;
  [...]

К этому:

server {
  server_name foo.example.com;
  error_log /var/log/nginx/foo.example.com.error_log debug;

Существующий error_log, серьезности нет:

Измените это:

server {
  server_name foo.example.com;
  error_log /var/log/nginx/foo.example.com.error_log;
  [...]

К этому:

server {
  server_name foo.example.com;
  error_log /var/log/nginx/foo.example.com.error_log debug;

Нет существующего error_log:

Измените это:

server {
  server_name foo.example.com;
  [...]

К этому:

server {
  server_name foo.example.com;
  error_log /var/log/nginx/foo.example.com.error_log debug;

Целевая отладка по IP-адресу

Если у вас загруженный сайт, даже включение отладки для одного виртуального хоста, скорее всего, приведет к серьезному снижению производительности (написание много логов на диск замедляет работу), и вам придется продираться через столько несущественной отладки, что вы никогда не поймете, что происходит.

В этом случае вы можете включить отладку только для запросов с определенных IP-адресов (например, с машины, с которой вы тестируете). Для этого вы хотите отредактировать основной файл конфигурации nginx (скажем, /etc/nginx/nginx.conf), Найти events раздел, и сделайте так:

events {
  debug_connection 192.0.2.42;
}

Заменить 192.0.2.42 с IP-адресом, который увидит nginx (возможно, общедоступный IP-адрес вашего шлюза NAT или вашего прокси, а не IP-адрес вашей рабочей станции). Перезагрузите nginx.

Теперь вы получите журналы отладки для всех подключений с этого IP-адреса (и только этот IP). Если вам нужно отлаживать запросы из нескольких мест, вы можете повторить debug_connection несколько раз или укажите маску сети в стиле CIDR для покрытия всего блока IP-адресов.

Отладка под лазерным наведением

Если вы решили, что вам нужно отлаживать просто запросы в данном location блок, вы можете добавить error_log директива в просто этот блок, и поэтому вы можете записывать журналы отладки в отдельное место. Что-то вроде этого поможет:

server {
  server_name foo.example.com;

  location ~ ^/somewhere/.*\.php {
    error_log /tmp/somewhere_php.log debug;
    [...]
  }
}

Теперь вы можете перезагрузить nginx, сделать запрос и заглянуть в /tmp/somewhere_php.log за все кровавые подробности. Просто не забудьте снова удалить директиву, когда закончите, иначе вы, вероятно, заполните свой /tmp перегородка в достаточно короткие сроки.