Pontos principais:
- Não se preocupe com
upstream
blocos para failover, se pingar um servidor trará outro para cima - não é possível dizer ao nginx (pelo menos, não à versão do FOSS) que o primeiro servidor está ativo novamente. O nginx tentará os servidores na primeira solicitação, mas não nas solicitações de acompanhamento, apesar das configuraçõesbackup
,weight
oufail_timeout
. - Você deve ativar
recursive_error_pages
ao implementar o failover usandoerror_page
e locais nomeados. - Ative o
proxy_intercept_errors
para lidar com códigos de erro enviados pelo servidor upstream. - A sintaxe
=
(por exemplo,error_page 502 = @handle_502;
) é necessária para manipular corretamente os códigos de erro no local nomeado. Se=
não for usado, o nginx usará o código de erro do bloco anterior.
Resposta original / registro de pesquisa:
Aqui está uma solução melhor que encontrei, o que é uma melhoria, pois não exige um redirecionamento de cliente:
upstream aba {
server $BACKEND-IP;
server 127.0.0.1:82 backup;
server $BACKEND-IP backup;
}
...
location / {
proxy_pass http://aba;
proxy_next_upstream error http_502;
}
Então, é só pegar o servidor de controle para retornar 502 em "sucesso" e esperar que o código nunca seja retornado pelos backends.
Atualização: o nginx continua marcando a primeira entrada no bloco upstream
como inativo, por isso não tenta os servidores em ordem em solicitações sucessivas. Eu tentei adicionar weight=1000000000 fail_timeout=1
à primeira entrada sem efeito. Até agora não encontrei nenhuma solução que não envolva um redirecionamento de cliente.
Edit: Mais uma coisa que eu gostaria de saber - para obter o status de erro do manipulador error_page
, use esta sintaxe: error_page 502 = @handle_502;
- o sinal de igual fará com que o nginx obtenha o status de erro do manipulador. p>
Edit: E eu tenho que trabalhar! Além da correção error_page
acima, tudo o que era necessário era ativar recursive_error_pages
!