Como funciona o reload do NGINX? Por que o NGINX não está fazendo hot-reload?

Wei Liu

September 30, 2022

Technology

Recentemente, notei uma postagem no Reddit que dizia "Por que o NGINX não suporta recarregamento a quente?". Estranhamente, o NGINX, o maior servidor web do mundo, não suporta recarregamento a quente? Isso significa que todos nós usamos nginx -s reload incorretamente? Com essa questão, vamos verificar como o recarregamento do NGINX funciona.

O que é o NGINX

O NGINX é um servidor web de código aberto e multiplataforma desenvolvido em linguagem C. De acordo com estatísticas, entre os 1000 sites com maior tráfego, mais de 40% deles usam o NGINX para lidar com as enormes solicitações.

Quais vantagens o NGINX tem para superar outros servidores web e manter sempre uma alta taxa de utilização?

A principal razão é que o NGINX foi projetado para lidar com problemas de alta concorrência. Portanto, o NGINX pode fornecer um serviço estável e eficiente ao lidar com um grande número de solicitações simultâneas. Além disso, em comparação com concorrentes da mesma época, como Apache e Tomcat, o NGINX possui muitos designs extraordinários, como arquitetura avançada orientada a eventos, um mecanismo totalmente assíncrono para lidar com IO de rede e um sistema de gerenciamento de memória extremamente eficiente. Esses designs notáveis ajudam o NGINX a utilizar totalmente os recursos de hardware dos servidores e tornam o NGINX sinônimo de servidor web.

Além do mencionado, há outras razões, como:

  1. Design altamente modular faz com que o NGINX possua uma grande quantidade de módulos oficiais e de terceiros ricos em recursos.
  2. A licença BSD mais livre faz com que os desenvolvedores contribuam voluntariamente para o NGINX.
  3. O suporte ao recarregamento a quente permite que o NGINX forneça serviços 24/7.

Entre as razões acima, o recarregamento a quente é o nosso principal tópico hoje.

O que o Recarregamento a Quente faz

O que esperamos do recarregamento a quente? Primeiro, acho que os usuários do lado do cliente não devem perceber que o servidor está sendo recarregado. Segundo, os servidores ou serviços upstream devem alcançar o carregamento dinâmico e lidar com todas as solicitações dos usuários com sucesso, sem tempo de inatividade.

Em que circunstâncias precisamos de recarregamento a quente? Na era da Nuvem Nativa, os microsserviços se tornaram tão populares que cada vez mais cenários de aplicação exigem modificações frequentes no lado do servidor. Essas modificações, como o proxy reverso de domínio online/offline, mudanças de endereço upstream e alterações na lista de permissões/bloqueios de IP, estão relacionadas ao recarregamento a quente.

Então, como o NGINX alcança o recarregamento a quente?

O Princípio do Recarregamento a Quente do NGINX

Quando executamos o comando de recarregamento a quente nginx -s reload, ele envia um sinal HUP para o processo mestre do NGINX. Quando o processo mestre recebe o sinal HUP, ele abre as portas de escuta sequencialmente e inicia um novo processo worker. Portanto, dois processos worker (antigo e novo) existirão simultaneamente. Após o novo processo worker entrar, o processo mestre enviará um sinal QUIT ao processo worker antigo para encerrá-lo graciosamente. Quando o processo worker antigo recebe o sinal QUIT, ele primeiro fecha o manipulador de escuta. Agora, todas as novas conexões entrarão apenas no novo processo worker, e o servidor encerrará o processo antigo assim que processar todas as conexões restantes.

Em teoria, o recarregamento a quente do NGINX poderia atender perfeitamente às nossas necessidades? Infelizmente, a resposta é não. Então, que tipo de desvantagens o recarregamento a quente do NGINX tem?

O recarregamento do NGINX causa tempo de inatividade

  1. Recarregamentos a quente muito frequentes tornariam as conexões instáveis e causariam perda de dados comerciais.

    Quando o NGINX executa o comando de recarregamento, o processo worker antigo continuará processando as conexões existentes e se desconectará automaticamente assim que processar todas as solicitações restantes. No entanto, se o cliente não tiver processado todas as solicitações, ele perderá os dados comerciais das solicitações restantes para sempre. Claro, isso chamaria a atenção dos usuários do lado do cliente.

  2. Em algumas circunstâncias, o tempo de reciclagem do processo worker antigo é tão longo que afeta o negócio regular.

    Por exemplo, quando fazemos proxy do protocolo WebSocket, não podemos saber se uma solicitação foi processada porque o NGINX não analisa o quadro de cabeçalho. Portanto, mesmo que o processo worker receba o comando de saída do processo mestre, ele não pode sair até que essas conexões gerem exceções, expirem ou se desconectem.

    Aqui está outro exemplo, quando o NGINX atua como proxy reverso para TCP e UDP, ele não pode saber com que frequência uma solicitação está sendo solicitada antes de finalmente ser encerrada.

    Portanto, o processo worker antigo geralmente leva muito tempo, especialmente em indústrias como transmissão ao vivo, mídia e reconhecimento de fala. Às vezes, o tempo de reciclagem do processo worker antigo pode chegar a meia hora ou até mais. Enquanto isso, se os usuários recarregarem o servidor com frequência, isso criará muitos processos em encerramento e, finalmente, levará ao OOM do NGINX, o que pode afetar seriamente o negócio.

# sempre existe no processo worker antigo:
nobody 6246 6241 0 10:51 ? 00:00:00 nginx: worker process
nobody 6247 6241 0 10:51 ? 00:00:00 nginx: worker process
nobody 6247 6241 0 10:51 ? 00:00:00 nginx: worker process
nobody 6248 6241 0 10:51 ? 00:00:00 nginx: worker process
nobody 6249 6241 0 10:51 ? 00:00:00 nginx: worker process
nobody 7995 10419 0 10:30 ? 00:20:37 nginx: worker process is shutting down  <= aqui
nobody 7995 10419 0 10:30 ? 00:20:37 nginx: worker process is shutting down
nobody 7996 10419 0 10:30 ? 00:20:37 nginx: worker process is shutting down

Em resumo, poderíamos alcançar o recarregamento a quente executando nginx -s reload, o que era suficiente no passado. No entanto, o rápido desenvolvimento dos microsserviços e da Nuvem Nativa faz com que essa solução não atenda mais às necessidades dos usuários.

Se a frequência de atualização do seu negócio for semanal ou diária, então esse NGINX recarregando ainda pode satisfazer suas necessidades. No entanto, e se a frequência de atualização se tornar horária ou por minuto? Por exemplo, suponha que você tenha 100 servidores NGINX, e ele recarrega uma vez por hora, então precisaria recarregar 2400 vezes por dia; Se o servidor recarregar por minuto, então precisará recarregar 8.640.000 vezes por dia, o que é inaceitável.

Precisamos de uma solução sem troca de processos, e que também possa alcançar atualizações de conteúdo imediatas.

Recarregamento a Quente que Entra em Efeito Imediatamente na Memória

Quando o Apache APISIX nasceu, ele foi projetado para resolver o problema de recarregamento a quente do NGINX. O APISIX é desenvolvido com base nas pilhas tecnológicas do NGINX e Lua, e é um gateway de API de microsserviços totalmente dinâmico, de alto desempenho e nativo da nuvem, que usa etcd como seu centro de configuração principal. Não há necessidade de reiniciar o servidor para recarregar a nova configuração do servidor, o que significa que qualquer alteração em serviços upstream, rotas ou plugins não exigirá uma reinicialização do servidor. Mas como o APISIX poderia eliminar as limitações do NGINX para alcançar um recarregamento a quente perfeito com base no fato de que o APISIX é desenvolvido sobre a pilha tecnológica do NGINX?

Primeiro, vamos ver a arquitetura de software do Apache APISIX:

Arquitetura

O APISIX pode alcançar o recarregamento a quente perfeito, pois coloca todas as configurações no APISIX Core e no Plugin Runtime para que possam usar atribuições dinâmicas. Por exemplo, quando o NGINX precisa configurar parâmetros dentro dos arquivos de configuração, cada modificação só entra em vigor após o recarregamento. Para configurar rotas dinamicamente, o Apache APISIX configura apenas um servidor específico com apenas um local. Temos que usar esse local como a entrada principal para que todas as solicitações passem por ele primeiro, e então o APISIX Core atribuirá dinamicamente os upstreams específicos para elas. O módulo de rota do Apache APISIX pode suportar adicionar/remover, modificar e excluir rotas enquanto o servidor está em execução. Em outras palavras, ele pode alcançar o recarregamento dinâmico. Nenhuma dessas alterações chamaria a atenção dos usuários e afetaria o negócio regular.

Agora, vamos introduzir um cenário clássico; por exemplo, se quisermos adicionar um proxy reverso para um novo domínio, só precisamos criar um upstream no APISIX e adicionar uma nova rota. O NGINX não precisa reiniciar durante esse processo. Aqui está outro exemplo para o sistema de plugins: o APISIX pode usar um plugin de restrição de IP para alcançar o recurso de lista de permissões/bloqueios de IP. Todas essas atualizações de recursos são dinâmicas e não exigem a reinicialização do servidor. Graças ao etcd, a estratégia de configuração pode alcançar atualizações instantâneas usando complementos, e todas as configurações podem entrar em vigor imediatamente e fornecer a melhor experiência do usuário.

Conclusão

O recarregamento a quente do NGINX teria um processo worker antigo e um novo em algumas circunstâncias, o que causa desperdício adicional de recursos. Além disso, recarregamentos a quente muito frequentes podem causar uma pequena chance de perda total de dados comerciais. No contexto da Nuvem Nativa e dos microsserviços, as atualizações de serviços se tornam cada vez mais frequentes, e a estratégia para gerenciar a API também varia, o que leva a novos requisitos para o recarregamento a quente.

O recarregamento a quente do NGINX não atende mais aos requisitos do negócio. É hora de mudar para o Apache APISIX, um gateway de API com uma estratégia de recarregamento a quente mais avançada na era da Nuvem Nativa. Além disso, após a mudança para o APISIX, os usuários podem ter um gerenciamento dinâmico e uniforme dos serviços de API, e isso pode melhorar significativamente a eficiência de gerenciamento.

Tags: