Recarregar Nova Configuração Nginx Sem Tempo de Inatividade

3

Eu tenho um servidor Nginx que lida constantemente com altas cargas de solicitações. Eu quero poder alterar o arquivo de configuração do servidor e recarregá-lo dinamicamente com tempo de inatividade zero.

Estou executando a seguinte linha no shell:

httperf --server=127.0.0.1 --port=80 --uri=/ --num-conns=1 --num-calls=10

E enquanto envia solicitações, estou recarregando minha configuração nginx. Eu tentei as duas opções a seguir:

sudo nginx -s reload

sudo kill -s HUP [pid]

Ambos fazem com que o httperf retorne alguns erros. Em média, após duas boas solicitações, o httperf fecha e imprime seu log, com a seguinte linha relevante:

Errors: total 1 client-timo 0 socket-timo 0 connrefused 0 connreset 1

Eu li em vários lugares que a recarga deve ser feita sem interrupções, mas a partir do teste que faço, as coisas parecem diferentes.

Minhas perguntas são:

  1. Estou realizando os testes de maneira errada? Por que estou recuperando essa conexão?
  2. Existe uma solução para este problema?
  3. Na verdade, preciso de um balanceador de carga que possa adicionar e remover dinamicamente servidores dele, qualquer solução melhor que seja adequada ao meu problema?

Agradecemos antecipadamente pela ajuda e esperamos ver algumas respostas perspicazes.

    
por Erez Rabih 15.07.2013 / 17:27

1 resposta

8

Para entender a resposta a seguir, é necessário algum plano de fundo:

Am I performing the tests in a wrong way?

Sim, você está realizando o teste de forma incorreta. O problema é que seu teste está usando conexão PERSISTENTE para enviar 10 solicitações. Você pode verificá-lo facilmente executando o seguinte teste e não terá redefinições de conexão (porque você envia apenas uma solicitação por conexão):

httperf --server=127.0.0.1 --port=80 --uri=/ --num-conns=10 --num-calls=1

Why am I getting this connection resets?

Se você olhar para a documentação do nginx , você encontrará o seguinte:

Old worker processes, receiving a command to shut down, stop accepting new connections and continue to service current requests until all such requests are serviced. After that, the old worker processes exit.

O que é verdade, mas a documentação não menciona o que está acontecendo com conexões persistentes. Encontrei resposta na antiga lista de discussão . Depois que a solicitação em execução no momento for veiculada, o nginx iniciará a conexão persistente fechando enviando [FIN, ACK] para o cliente.

Para verificar isso, usei o WireShark e configurei o servidor com um trabalhador simples, que sob demanda dorme 5 segundos e depois responde. Eu usei o seguinte comando para enviar solicitação:

httperf --server=127.0.0.1 --port=80 --uri=/ --num-conns=1 --num-calls=2

Depois de emitir o comando mencionado anteriormente, recarreguei o nginx (enquanto ele estava manipulando a primeira solicitação). Aqui estão os pacotes cheirados por WireShark:

  • 3892-3894-estabelecimentohabitualdeconexãoTCP.
  • 3895-oclienteenviouoprimeiropedido.
  • 3896-oservidorconfirma3895.
  • aquinginxreloadfoiexecutado.
  • 4089-respostaenviadapeloservidor.
  • 4090-servidorenviousinaldeconexãopróxima.
  • 4091-oclientereconhece4089.
  • 4092-oclienteconfirma4090.
  • 4093-segundasolicitaçãoenviadapelocliente(WTF?)
  • 4094-oclienteenviouumsinaldeconexãopróxima.
  • 4095-oservidorconfirma4093.
  • 4096-oservidorconfirma4094.

Issoéok,esseservidornãoenviounenhumarespostaparaosegundopedido.Deacordocom terminação da conexão TCP :

The side that has terminated can no longer send any data into the connection, but the other side can. The terminating side should continue reading the data until the other side terminates as well.

Próxima pergunta é por que 4093 aconteceu depois que o cliente recebeu sinal de conexão próxima do servidor?

Provavelmente esta é a resposta :

I would say that the POST happens at the same time as the FIN, i.e. the client sent the POST because its TCP stack did not process the FIN from the server yet. Note that packet capturing is done before the data are processed by the system.

Eu não posso comentar sobre isso, já que não sou especialista em networking. Talvez outra pessoa possa dar uma resposta mais perspicaz por que o segundo pedido foi enviado.

UPD A pergunta relacionada anteriormente não é relevante. Perguntou pergunta separada sobre o problema.

Is there a solution to this problem?

Como foi mencionado na lista de discussão :

HTTP/1.1 clients are required to handle keepalive connection close, so this shouldn't be a problem.

Eu acho que deve ser tratado no lado do cliente. E se a conexão for fechada pelo servidor, o cliente deverá abrir uma nova conexão e tentar novamente a solicitação.

I actually need a load balancer which I can dynamically add and remove servers from it, any better solutions which fits my problem?

Eu não sei sobre outros servidores, então não posso aconselhá-lo aqui.

Assim que seus clientes puderem lidar com o fechamento da conexão corretamente, não haverá motivos para impedir o uso do nginx.

    
por 12.08.2015 / 15:50