Como fazer o nginx try_files obter recursos html em tempo hábil

1

Usando nginx 1.8.1 em uma instância Amazon Linux EC2 . Usando como proxy reverso para suportar https para Apache em execução em uma instância diferente. Tudo está funcionando bem, exceto por esse problema.

Desejo exibir uma página estática de nginx no caso de querer remover a instância Apache do servidor. Então eu fiz isso:

    location   / {
        try_files /site-down.html $uri @backend;
    }

Portanto, antes de desligar o servidor de back-end, eu crio um link simbólico no diretório-raiz do servidor nginx para um arquivo html estático que se parece com isto:

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8">

  <title>example.com</title>
  <style type="text/css">
  body {
    background-image:url('/images/back-soon-background.jpg');
    font-family: arial,verdana,sans-serif;
    text-align: center;
  }
  #msg {
    background-image: url('/images/back-soon-oval.png');
    background-repeat: no-repeat;
    width: 600px;
    padding-top: 140px;
    padding-left: 50px;
    padding-right: 50px;
    padding-bottom: 150px;
  }
  </style>
</head>

<body>
<div id="msg">
<h1>Sorry, the site is currently unavailable.</h1>
<h2>We expect to be back within 2 hours.</h2>
</div>
</body>
</html>

O problema é que, quando faço isso, a página é exibida imediatamente como apenas o conteúdo de texto de div , sem as imagens especificadas pela <style> na seção <head> . Com a guia "Ferramentas de desenvolvedor Chrome " da Rede, posso ver solicitações de saída dos URLs de imagem e obter 200 códigos de status. Mas se eu clicar nessas solicitações, não haverá visualização disponível e o comprimento do corpo será muito curto. Recarregar a página não ajuda imediatamente. Mas se eu deixar ficar lá por um tempo, eventualmente a saída correta com as imagens aparece. Se eu apontar meu navegador diretamente para /site-down.html , a página será exibida imediatamente.

Tanto Chrome 52.0.2743.116 m como Firefox 48.0.2 se comportam da mesma maneira. Sou novo em nginx , mas não consigo imaginar por que o primeiro uri em um try_files deve se comportar de maneira diferente de ir diretamente para esse uri no caso em que o arquivo existe. O que estou perdendo?

    
por sootsnoot 09.09.2016 / 22:22

3 respostas

1

Os comentários de @ Michael-Hampton deram a resposta para a pergunta que eu fiz. Sugeri há cerca de 6 semanas que, se ele postasse essa informação como resposta, eu a marcaria como aceita. Mas desde que ele não fez isso, estou construindo uma resposta aqui para aceitar. Parece uma pena deixar isso sem resposta.

A resposta à pergunta, como eu perguntei, é que a configuração nginx que eu especifiquei forçou all solicitações para primeiro tentar veicular a página estática site-down.html . E como as imagens foram especificadas como URLs para o mesmo site, essas solicitações de imagem também foram manipuladas pela diretiva / location , portanto, o try_files foi aplicado e alterado também para exibir a página site-down.html .

Eu não sei por que as imagens apareceram depois de algumas recargas e espera, algo deve ter expirado.

A maneira mais direta de resolver o problema, como eu estava vendo, foi alterar o URL da imagem de plano de fundo em data url com o próprio conteúdo da imagem incorporado em base64 strings. Ao fazer isso, a página site-down.html não gera solicitações adicionais de recursos e funciona como pretendi originalmente.

Mas ele também observou que o que eu estou tentando fazer, ao trabalhar, dá um código de status 200, embora o site esteja basicamente inativo. Expliquei que o site é destinado apenas a usuários interativos, não a servidores, e isso é para interrupções intencionais de curto prazo, não para erros como uma falha de servidor de back-end. Então eu não vejo isso como um grande problema. Mas a verdade é que é sempre melhor dar um código de status significativo. Então eu acho que a solução "certa" para mim é ter dois arquivos de configuração nginx "disponíveis" diferentes, um dos quais simplesmente codifica uma resposta 503 usando site-down.html como uma página de erro personalizada. Então, ao invés de criar / remover um link simbólico chamado site-down.html na raiz, e confiar em try_files para dar o comportamento desejado, eu deveria apenas mudar o symlink no diretório habilitado para sites para selecionar a configuração correta e fazer um sudo service nginx reload para alternar suavemente comportamentos.

A vantagem de usar try_files é que o comportamento muda imediatamente com um comando, enquanto a desvantagem é que o código de status indica que o site está funcionando bem, embora não esteja. A vantagem de trocar arquivos de configuração é que ele fornece um status significativo, enquanto a desvantagem é que a etapa extra de recarregar o nginx é algo que pode ser esquecido. No entanto, no final, o switch será feito por um script e o script não esquecerá de recarregar a configuração.

    
por 10.09.2016 / 15:40
0

try_files tenta arquivos na ordem que você especificar. Altere a ordem para algo como isto

try_files $uri @backend /site-down.html;

Eu assumo desde que a página está sendo servida agora você tem tudo configurado ok. Dê uma chance e comente a resposta se precisar de mais ajuda. Certifique-se de incluir registros, se aplicável.

    
por 09.09.2016 / 22:29
0

Use a diretiva error_page para lidar com a situação quando o back-end estiver inativo. Isso também permitirá que você retorne um código de resposta HTTP adequado.

Por exemplo:

server {
    try_files $uri @backend;

    error_page 500 502 503 504 =503 /site-down.html;

    #....

Neste caso, servimos primeiro os arquivos estáticos e, em seguida, vamos para o backend. Se o backend retornar um dos erros listados, o nginx exibirá /site-down.html com uma resposta HTTP 503.

O benefício deste método é que você não precisa adicionar ou remover manualmente o arquivo site-down.html . Você o deixa no lugar, e o nginx o servirá automaticamente se o backend estiver realmente para baixo.

    
por 09.09.2016 / 23:22