Para entender a resposta a seguir, é necessário algum plano de fundo:
- O que é conexão persistente HTTP .
- Noções básicas de protocolo TCP e particularmente final da conexão do fluxo de trabalho.
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.
- aqui
nginxreload
foiexecutado. - 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
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.