На этот вопрос нужно было ответить давным-давно, но я не могу понять этого, несмотря на то, что читал много общих ответов, может кто-нибудь указать, почему моя конфигурация не работает?
Цель: когда вышестоящий server_api не работает (например, его рабочие процессы вышли из строя), я хочу, чтобы nginx отображал мою пользовательскую страницу с ошибкой.
Моя конфигурация:
location @server {
proxy_pass http://server_api;
proxy_redirect off;
...
proxy_intercept_errors on;
error_page 502 /error-502.html;
}
error_page 502 /error-502.html;
location = /error-502.html {
internal;
root /srv/my-server/html;
}
Мои шаги:
/srv/my-server/html/error-502.html
готово, те же права и владельцы, что и другие статические активы.[error] 2359#0: *25 connect() failed (111: Connection refused) while connecting to upstream
появляется в журналах.error_page
на обоих или на одном server
или location
блок.error_page
с участием proxy_intercept_errors on
в location
или server
блок;Ни один из них не убедил nginx отобразить мою страницу с ошибкой. Почему нет? Что я пропустил?
Спасибо Джастину и Майклу за то, что они указали мне правильное направление, это действительно блокировка местоположения, вызывающая мои проблемы, в частности:
location / {
try_files $uri $uri/ @server;
error_page 403 = @server;
}
В принципе, я пытался быть умным и уловить $uri/
ошибка (403 происходит, когда вы пытаетесь получить доступ к папке, которая существует, но не имеет индексного файла или автоматической индексации) и перенаправляете ее на @server
блок тоже.
Но не try_files $uri $uri/ @server;
достаточно одного?
Представьте, что вы пытаетесь получить доступ http://example.com/
, nginx скажет, что эта папка существует (это ваша root
), но индекс не найден, и бросить 403 вместо передачи @server
блок.
Таким образом, мое решение 403, но я не осознавал, что оно связано с расходами: это означает, что nginx уже обнаружил ошибку и использовал error_page
В то же самое location
блок для обработки (передав его в @server
).
Соедините это с моими тестами в вопросе, он предполагает, что nginx (v1.7.x) будет игнорировать дальше error_page
и используйте вместо нее значение по умолчанию 502.
Интересная часть: как нам обойти это?
Мое решение состоит в том, чтобы вместо этого настроить точное соответствие корневого маршрута, теперь ловить 403 на корне больше не нужно, и error_page
работает по назначению.
error_page 502 /error-502.html;
location = /error-502.html {
internal;
root /srv/example.com/html;
}
location = / {
try_files $uri @server;
}
location / {
try_files $uri $uri/ @server;
}
Трудно сказать наверняка, не увидев всю вашу конфигурацию, потому что это работает для меня без каких-либо дополнительных мер, которые вы предприняли. Сначала я попробовал всю вашу конфигурацию, а затем удалил биты один за другим, чтобы посмотреть, не изменилось ли что-нибудь.
Нет необходимости использовать proxy_intercept_errors, потому что 502 генерируется самим nginx, когда ему не удается подключиться к бэкэнду. Я подтвердил, что это сработало для меня с этим набором и отключенным.
Все, что я добавил в свой серверный блок:
error_page 502 /error-502.html;
location = /error-502.html {
internal;
root /srv/www/errors;
}
В моей настройке мои статические страницы ошибок находятся в / srv / www / errors, но все остальное не отличается.
У вас должна быть конфигурация где-нибудь на уровне сервера или в блоке вашего сервера, который мешает или отменяет. Обратите внимание на правила приоритета локаций, это может быть фактором.