Captura de erros upstream down (502) e exibe a página de erro personalizada

2

Esta questão deveria ter sido respondida há muito tempo, mas não consigo descobrir, apesar de ler muitas respostas comuns, alguém pode por favor apontar porque minha configuração não está funcionando?

Objetivo: quando o upstream server_api está inativo (digamos, seus processos de trabalho falharam), quero que o nginx exiba minha página de erro personalizada.

Minha configuração:

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;
}

Meus passos:

  • Tenho minha página de erro estático em /srv/my-server/html/error-502.html pronto, mesma permissão e proprietários de outros recursos estáticos.
  • Parei meu serviço de envio e vejo [error] 2359#0: *25 connect() failed (111: Connection refused) while connecting to upstream aparecendo nos registros.
  • Agora, tento tornar minha página de erro personalizada exibida para 502 erros.
  • Tentei definir error_page em ambos ou server ou location block.
  • Eu tentei error_page com proxy_intercept_errors on no bloco location ou server ;

Nenhum deles parece convencer o nginx a exibir minha página de erro. Por que não? O que eu perdi?

    
por bitinn 04.04.2015 / 20:33

2 respostas

4

Obrigado Justin e Michael por me apontar na direção certa, é de fato um bloco de localização causando meus problemas, em particular:

location / {
    try_files   $uri $uri/ @server;
    error_page  403 = @server;
}

Basicamente, eu estava tentando ser inteligente e pegar o erro $uri/ (403 acontece quando você tenta acessar uma pasta que existe, mas não tem nenhum arquivo de índice ou auto-indexação) e também redireciona para @server block.

Mas não é try_files $uri $uri/ @server; sozinho o suficiente?

Imagine que você está tentando acessar http://example.com/ , nginx dirá, oh esta pasta existe (é seu root ) mas nenhum índice encontrado, e lança 403 em vez de passar para @server bloco.

Assim, minha solução 403, mas não percebi que ela vem com um custo: isso significa que nginx já pegou um erro e usou error_page no mesmo bloco location para manipulá-lo (passando-o para @server ).

Junte isso com meus testes na pergunta, isso sugere que nginx (v1.7.x) irá ignorar mais a diretiva error_page neste ponto e usar o padrão 502 ao invés.

A parte interessante: como podemos resolver isso?

Minha solução é configurar uma rota raiz exata em vez disso, agora capturar 403 na raiz não é mais necessário, e error_page funciona como pretendido.

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;
}
    
por 05.04.2015 / 09:21
1

É difícil dizer com certeza, sem ver sua configuração inteira, porque isso funciona para mim sem nenhuma das medidas extras que você tomou. Primeiro tentei toda a sua configuração, depois tirei os bits, um por um, para ver se alguma coisa mudava.

Não deve ser necessário usar proxy_intercept_errors, porque o 502 é gerado pelo próprio nginx quando não consegue se conectar ao backend. Eu confirmei que isso funcionou para mim com esse conjunto e não definido.

Tudo que eu adicionei, dentro do meu bloco de servidor é:

error_page 502 /error-502.html;

location = /error-502.html {
  internal;
  root /srv/www/errors;
}

Na minha configuração, minhas páginas de erro estático estão em / srv / www / errors, mas nada é diferente.

Você deve ter configuração em outro lugar que seja em todo o servidor ou em seu bloco de servidor que interfira ou substitua. Preste atenção nas regras de precedência para locais, que poderiam ser um fator.

    
por 04.04.2015 / 22:03