Я намагаюся налаштувати nginx як зворотний проксі-сервер із великою кількістю серверних сервера. Я хотів би запустити резервні копії на вимогу (за першим запитом, який надходить), тому у мене є процес управління (керований HTTP-запитами), який запускає бекенд залежно від запиту, який він отримує.
Моя проблема полягає в налаштуванні nginx для цього. Ось що я маю досі:
server {
listen 80;
server_name $DOMAINS;
location / {
# redirect to named location
#error_page 418 = @backend;
#return 418; # doesn't work - error_page doesn't work after redirect
try_files /nonexisting-file @backend;
}
location @backend {
proxy_pass http://$BACKEND-IP;
error_page 502 @handle_502; # Backend server down? Try to start it
}
location @handle_502 { # What to do when the backend server is not up
# Ping our control server to start the backend
proxy_pass http://127.0.0.1:82;
# Look at the status codes returned from control server
proxy_intercept_errors on;
# Fallback to error page if control server is down
error_page 502 /fatal_error.html;
# Fallback to error page if control server ran into an error
error_page 503 /fatal_error.html;
# Control server started backend successfully, retry the backend
# Let's use HTTP 451 to communicate a successful backend startup
error_page 451 @backend;
}
location = /fatal_error.html {
# Error page shown when control server is down too
root /home/nginx/www;
internal;
}
}
Це не працює - схоже, що nginx ігнорує будь-які коди статусу, повернені з сервера управління. Жодна error_page
директива в @handle_502
локації не працює, і код 451 надсилається клієнтові як є.
Я відмовився від спроби використовувати внутрішнє перенаправлення nginx для цього, і спробував змінити керуючий сервер, щоб він передавав переспрямування 307 в ту саму локацію (щоб клієнт повторював той самий запит, але тепер із запущеним сервером запуску). Однак тепер nginx тупо замінює код статусу тим, який він отримав із спроби резервного запиту (502), незважаючи на те, що сервер управління надсилає заголовок "Location". Зрештою, я його "працюю", змінивши рядок сторінки помилок наerror_page 502 =307 @handle_502;
, таким чином, змушуючи всі відповіді сервера управління надсилатися назад клієнту з кодом 307. Це дуже хитро і небажано, тому що 1) немає контролю над тим, що nginx повинен робити далі, залежно від відповіді сервера управління (в ідеалі ми хочемо повторити спробу лише в тому випадку, якщо сервер управління повідомляє про успіх), і 2) не весь HTTP клієнти підтримують переспрямування HTTP (наприклад, користувачі curl та додатки, що використовують libcurl, повинні включати явні наступні переадресації).
Який правильний спосіб отримати nginx, щоб спробувати проксі-сервер на верхньому сервері A, потім B, потім A знову (в ідеалі, лише коли B повертає певний код статусу)?
proxy_next_upstream
зробив трюк (добре, що мій сценарій був не таким складним, як ваш), я просто хотів nginx спробувати наступний сервер, якщо сталася помилка, тому мені довелося додатиproxy_next_upstream error timeout invalid_header non_idempotent;
(non_idempotent
тому що я хочу в основному пересилатиPOST
запити).