Ao remover um servidor de back-end ou quando ele falha em uma verificação de integridade, as conexões estabelecidas não são encerradas imediatamente. O fechamento abrupto dessas conexões pode interromper requisições em andamento e impedir o desligamento correto dos serviços. Para evitar esse problema, utilize o recurso de connection draining do Application Load Balancer (ALB). Quando um servidor de back-end é removido ou reprovado na verificação de integridade, o connection draining mantém as conexões existentes ativas por um período configurado. Após o término desse tempo limite, o ALB fecha as conexões para garantir um desligamento adequado.
Casos de uso
O connection draining aplica-se aos dois cenários a seguir.
Remoção de servidor de back-end: antes de remover um servidor de back-end, defina um tempo limite maior para o connection draining, permitindo a conclusão das requisições em andamento.
Falha na verificação de integridade: para um servidor de back-end com falha na verificação de integridade, configure um tempo limite menor para encerrar rapidamente as conexões defeituosas e evitar que os clientes recebam erros de conexão.
Como ambos os cenários compartilham a mesma configuração de connection draining, defina um tempo limite adequado aos requisitos do seu negócio.
Remove backend server
A figura a seguir mostra um exemplo. Ao remover o servidor de back-end ECS01, o ALB deixa de enviar novas requisições para ele. O ECS01 passa a processar apenas as requisições em andamento e não aceita novas requisições.
Se o connection draining estiver desativado, o ECS01 fechará a sessão somente após processar todas as requisições em andamento.
-
Caso o connection draining esteja ativado e um tempo limite seja definido:
Se o servidor de back-end removido ECS01 tiver requisições em andamento, o ALB fechará as sessões existentes no ECS01 após o término do tempo limite do connection draining.
Se o servidor de back-end removido ECS01 não tiver requisições em andamento nem conexões ativas, o ALB concluirá imediatamente o processo de remoção, sem aguardar o término do tempo limite do connection draining.
Se o servidor de back-end removido ECS01 estiver processando uma requisição quando o processo de remoção terminar, a conexão será encerrada e o cliente receberá uma resposta de erro 500. Por exemplo, se o tempo limite do connection draining for definido como 15 segundos, mas o tempo de processamento da requisição no ECS01 for de 30 segundos, a conexão será encerrada antes que o ECS01 possa enviar uma resposta. Nesse caso, o cliente recebe uma resposta de erro 500.
NotaSe você readicionar o ECS01 ao grupo de servidores, isso não afetará as sessões que já estão em draining. O ECS01 permanece no estado de draining — processando apenas requisições em andamento — até que as sessões existentes sejam fechadas. O ALB fecha essas sessões quando o tempo limite do connection draining expira.
A figura a seguir ilustra as transições de estado do ECS01 após sua remoção de um grupo de servidores com o connection draining ativado.
Health check failure
Quando o servidor de back-end ECS01 falha em uma verificação de integridade, o ALB para de enviar novas requisições para ele. O ECS01 processa então apenas as requisições em andamento e não aceita novas requisições.
Se o connection draining estiver desativado, o ECS01 permanecerá nesse estado até ser aprovado na verificação de integridade. Após a aprovação, ele começará a aceitar novas requisições.
-
Se o connection draining estiver ativado e um tempo limite for definido:
O ALB fecha as sessões existentes no ECS01 após o término do tempo limite do connection draining.
Se você atualizar o grupo de servidores (por exemplo, modificando a configuração do ECS01), o estado da conexão não será alterado; ele continuará processando apenas requisições em andamento. Mesmo que o ECS01 seja aprovado em uma verificação de integridade após a atualização, o ALB ainda fechará suas sessões existentes quando o tempo limite do connection draining expirar.
NotaApós o término do tempo limite do connection draining e o fechamento das sessões pelo ALB, o ECS01 só poderá aceitar novas requisições se for aprovado na verificação de integridade. Caso continue falhando, não aceitará novas requisições.
O connection draining é acionado apenas por falhas na verificação de integridade causadas por problemas no serviço de back-end, e não por falhas resultantes de atualizações de configuração.
A figura a seguir mostra as transições de estado do ECS01 após uma falha na verificação de integridade.
É possível configurar o connection draining de acordo com o cenário do seu negócio. Este tópico usa o Cenário 1: Remover um servidor de back-end como exemplo para demonstrar como configurar o encerramento de sessões WebSocket e HTTP.
Observações de uso
Apenas instâncias ALB Standard e com WAF ativado suportam connection draining, enquanto instâncias ALB Basic não oferecem suporte a esse recurso.
Grupos de servidores do Function Compute não suportam connection draining.
O connection draining é eficaz tanto para sessões WebSocket quanto HTTP. Para sessões HTTP, recomenda-se definir o connection draining timeout com um valor superior ao connection request timeout do ALB, evitando assim o fechamento inesperado de requisições. Os valores padrão de tempo limite já seguem essa recomendação. Para obter informações sobre como definir o tempo limite de requisição de conexão, consulte Adicionar um listener HTTP.
Pré-requisitos
Uma instância ALB Standard ou com WAF ativado foi criada, e um grupo de servidores do tipo Server foi criado para essa instância ALB. Este tópico utiliza uma instância ALB Standard como exemplo. Para mais informações, consulte Criar uma instância ALB e Criar e gerenciar um grupo de servidores.
Um listener HTTP na porta
80foi configurado para a instância ALB e associado ao grupo de servidores. Para mais informações, consulte Adicionar um listener HTTP.Dois servidores de back-end, ECS01 e ECS02, foram criados. Para mais informações, consulte Criar uma instância usando o assistente.
-
O ECS02 foi adicionado ao grupo de servidores e está acessível a partir do cliente. Para mais informações, consulte Usar o ALB para alcançar balanceamento de carga para serviços IPv4 e Usar o ALB para alcançar balanceamento de carga para serviços IPv6.
NotaEste tópico utiliza um sistema operacional Alibaba Cloud Linux 3.2104 de 64 bits como cliente. Certifique-se de que o Python esteja instalado tanto no cliente quanto no servidor de back-end ECS01. Se o Python não estiver instalado, consulte o site oficial do Python para obter instruções. Este tópico usa o Python 3.x como exemplo.
Neste tópico, o ECS02 é o servidor de back-end que atende ao tráfego de produção. Se você já possui esse servidor de back-end, não é necessário criar outro.
Procedimento
Após ativar o connection draining e definir um período de tempo limite, este tópico demonstra como o ALB lida com requisições para sessões WebSocket e HTTP em diferentes estados de connection draining.
WebSocket sessions
Etapa 1: Ativar o connection draining
Um grupo de servidores foi criado como pré-requisito. Esta etapa mostra como ativar o connection draining para um grupo de servidores existente. Também é possível ativar esse recurso durante a criação do grupo.
Faça login no console do ALB.
Na barra de navegação superior, selecione a região onde o grupo de servidores está implantado.
No painel de navegação à esquerda, escolha ALB > Server Groups.
Na página Server Groups, localize o grupo de servidores desejado e clique em seu ID.
Na aba Details, na seção Basic Information, clique em Modify Basic Information.
Na caixa de diálogo Modify Basic Information, clique em Advanced Settings e ative a opção Connection Draining.
Defina o Timeout Period como 300 segundos e clique em Save.
Etapa 2: Verificar os resultados
Configurar o servidor
Faça login na instância ECS01. Para mais informações, consulte Métodos de conexão.
-
Execute os comandos a seguir para criar e acessar um diretório WebSocket:
mkdir WebSocket cd WebSocket -
Execute o comando a seguir para instalar as dependências:
pip install tornado pip install websocket-client -
Execute o comando a seguir para editar o arquivo de configuração server.py:
vim server.py-
Pressione
ipara entrar no modo de edição e adicione as configurações a seguir para iniciar um serviço WebSocket:#!/usr/bin/env python3 # encoding=utf-8 import tornado.websocket import tornado.ioloop import tornado.web from datetime import datetime # WebSocket handler class WebSocketHandler(tornado.websocket.WebSocketHandler): def open(self): current_time = datetime.now() formatted_time = current_time.strftime("%Y-%m-%d %H:%M:%S") print("Time:", formatted_time, "WebSocket connection opened") def on_message(self, message): current_time = datetime.now() formatted_time = current_time.strftime("%Y-%m-%d %H:%M:%S") print("Time:", formatted_time, "Received message:", message) self.write_message("Server received your message: " + message) def on_close(self): current_time = datetime.now() formatted_time = current_time.strftime("%Y-%m-%d %H:%M:%S") print("Time:", formatted_time, "WebSocket connection closed") # Routing application = tornado.web.Application([ (r"/websocket", WebSocketHandler), ]) if __name__ == "__main__": print("WebSocket Server Start on 8080 ...") application.listen(8080) tornado.ioloop.IOLoop.current().start() Após modificar o arquivo de configuração, pressione a tecla
Esc, insira:wqe pressione Enter para salvar e fechar o arquivo.
-
-
Acesse o diretório onde o server.py está armazenado e execute o comando a seguir para iniciar o serviço WebSocket:
python3 server.pyA resposta a seguir indica que o serviço de back-end WebSocket foi iniciado.
Websocket Server Start on 8080 ...
Adicionar o ECS01 ao grupo de servidores
Faça login no console do ALB.
Na barra de navegação superior, selecione a região onde o grupo de servidores está implantado.
No painel de navegação à esquerda, escolha ALB > Server Groups.
Na página Server Groups, localize o grupo de servidores desejado e clique em Modify Backend Server na coluna Actions.
Na aba Backend Servers, clique em Add Backend Server. No painel Add Backend Server, selecione o ECS01 e clique em Next.
Na etapa Ports/Weights, selecione a instância ECS01, defina a porta como
8080e clique em OK.
Configurar o cliente
-
Faça login no cliente e abra a interface de linha de comando (CLI). Execute os comandos a seguir para criar e acessar um diretório WebSocket:
mkdir WebSocket cd WebSocket -
Execute o comando a seguir para instalar as dependências:
pip install websocket-client -
Execute o comando a seguir para editar o arquivo client.py:
vim client.py-
Pressione
ipara entrar no modo de edição e adicione as configurações a seguir para iniciar um cliente WebSocket e acessar o serviço:#!/usr/bin/env python3 # encoding=utf-8 import websocket import time from datetime import datetime def on_message(ws, message): print("Received message from server:", message) if __name__ == "__main__": ws = websocket.WebSocket() ws.connect("ws://<domain_name>:80/websocket") # Replace <domain_name> with your actual domain name. print("WebSocket connection opened") try: while True: current_time = datetime.now() formatted_time = current_time.strftime("%Y-%m-%d %H:%M:%S") print("Sending time:", formatted_time) ws.send("Hello, Server!") result = ws.recv() on_message(ws, result) time.sleep(1) except Exception: print("WebSocket connection closed") Após modificar o arquivo de configuração, pressione a tecla
Esc, insira:wqe pressione Enter para salvar e fechar o arquivo.
-
-
Acesse o diretório onde o client.py está armazenado e execute o comando a seguir para acessar o servidor de back-end ECS01:
python3 client.pyA resposta a seguir indica que o acesso foi bem-sucedido.
WebSocket connection opened Sending time: 2024-04-28 17:00:53 Received message from server: Server received your message: Hello, Server! Sending time: 2024-04-28 17:00:54 Received message from server: Server received your message: Hello, Server!O servidor de back-end ECS01 retorna a seguinte resposta.
WebSocket Server Start on 8080 ... Time: 2024-04-28 17:00:53 WebSocket connection opened Time: 2024-04-28 17:00:53 Received message: Hello, Server! Time: 2024-04-28 17:00:54 Received message: Hello, Server!
Remover o servidor de back-end
Defina o tempo limite do connection draining antes de remover o servidor de back-end.
Faça login no console do ALB.
Na barra de navegação superior, selecione a região onde o grupo de servidores está implantado.
No painel de navegação à esquerda, escolha ALB > Server Groups.
Localize o grupo de servidores desejado e clique em seu ID.
Clique na aba Backend Servers, localize o servidor de back-end ECS01 desejado e clique em Remove na coluna Actions.
Na caixa de diálogo Remove, clique em OK.
Aguardar o connection draining
O Timeout Period está definido como 300 segundos. Os resultados do teste mostram que o ALB encerra a sessão cerca de 300 segundos após a remoção do ECS01.
Nos resultados do teste, a diferença de tempo entre a abertura e o fechamento da conexão WebSocket no servidor ECS01 é de 330 segundos. O período de tempo limite do connection draining, que corresponde à duração desde a remoção do servidor de back-end ECS01 até o fechamento da conexão WebSocket, é de aproximadamente 300 segundos.
-
O cliente retorna a seguinte resposta.
Sending time: 2024-04-28 17:06:23 Received message from server: Server received your message: Hello, Server! Sending time: 2024-04-28 17:06:24 WebSocket connection closed -
A instância do servidor ECS01 retorna a seguinte resposta.
Time: 2024-04-28 17:06:22 Received message: Hello, Server! Time: 2024-04-28 17:06:23 Received message: Hello, Server! Time: 2024-04-28 17:06:23 WebSocket connection closed
HTTP sessions
Em cenários HTTP, a resposta recebida pelo cliente varia conforme as configurações de connection draining timeout, connection request timeout e backend server processing time.
Se o connection draining timeout for menor que o backend server processing time, a conexão será interrompida antes que o ECS01 envie uma resposta. Nesse caso, o cliente recebe uma resposta de erro 500.
Caso o backend server processing time seja maior que o connection request timeout, a requisição para o ECS01 atingirá o tempo limite. Nessa situação, o cliente recebe uma resposta de erro 504.
Este tópico utiliza um connection draining timeout de 15 segundos e um backend server processing time de 30 segundos como exemplo. Nesse cenário, a conexão é interrompida antes que o ECS01 termine de enviar a resposta, e o cliente recebe uma resposta de erro 500.
Um erro 504 não é retornado porque o connection request timeout (60 segundos, definido na Etapa 2) é maior que o backend server processing time (30 segundos). Em vez disso, ocorre um erro 500 porque o connection draining timeout (15 segundos) é menor que o tempo de processamento do servidor.
Este tópico utiliza a função
time.sleepno código Python para simular o backend server processing time.
Etapa 1: Ativar o connection draining
Um grupo de servidores foi criado como pré-requisito. Esta etapa mostra como ativar o connection draining para um grupo de servidores existente. Também é possível ativar esse recurso durante a criação do grupo.
Faça login no console do ALB.
Na barra de navegação superior, selecione a região onde o grupo de servidores está implantado.
No painel de navegação à esquerda, escolha ALB > Server Groups.
Na página Server Groups, localize o grupo de servidores desejado e clique em seu ID.
Na aba Details, na seção Basic Information, clique em Modify Basic Information.
Na caixa de diálogo Modify Basic Information, clique em Advanced Settings e ative a opção Connection Draining.
Defina o Timeout Period como 15 segundos e clique em Save.
Etapa 2: Definir o tempo limite de requisição do ALB
Faça login no console do ALB.
Na barra de navegação superior, selecione a região onde a instância ALB está implantada.
Na página Instances, localize a instância ALB desejada e clique em seu ID.
Clique na aba Listener, localize o listener HTTP desejado e clique em seu ID.
Na área Basic Information, clique em Modify Listener.
Na caixa de diálogo Modify Listener, clique em Modify ao lado de Advanced Settings.
Defina o Connection Request Timeout como 60 segundos (valor padrão) e clique em Save.
Etapa 3: Configurar a resolução de DNS
Para ambientes de produção, recomenda-se mapear um nome de domínio personalizado para o nome de domínio da instância ALB criando um registro CNAME.
No painel de navegação à esquerda, escolha .
Na página Instances, copie o nome dns da instância ALB criada.
-
Siga estas etapas para adicionar um registro CNAME.
NotaSe o seu nome de domínio estiver registrado em um provedor diferente da Alibaba Cloud, será necessário adicionar o nome de domínio ao console do Alibaba Cloud DNS antes de configurar a resolução de DNS. Para mais informações, consulte Gerenciar nomes de domínio. Se o seu nome de domínio estiver registrado na Alibaba Cloud, prossiga com as etapas a seguir.
Faça login no console do Alibaba Cloud DNS.
Na página Authoritative DNS Resolution, localize o nome de domínio desejado e clique em Settings na coluna Operations.
Na página Settings, clique em Add Record.
-
No painel Add Record, configure o registro CNAME definindo os parâmetros a seguir e clique em OK.
Parâmetro
Descrição
Record Type
Selecione CNAME na lista suspensa.
Hostname
O prefixo do seu nome de domínio. Este tutorial utiliza @.
NotaPara usar um domínio raiz, defina o hostname como
@.Query Source
Selecione Default.
Record Value
Insira o nome dns da instância ALB que você copiou.
TTL
O Time to live (TTL) é a duração durante a qual um registro DNS fica armazenado em cache em um servidor DNS. Utilize o valor padrão.
Etapa 4: Verificar os resultados
Configurar o servidor
Faça login na instância ECS01. Para mais informações, consulte Métodos de conexão.
-
Execute os comandos a seguir para criar e acessar um diretório HTTP:
mkdir http cd http -
Execute o comando a seguir para editar o arquivo de configuração http_server.py:
vim http_server.py-
Pressione
ipara entrar no modo de edição e adicione as configurações a seguir para iniciar um serviço de servidor HTTP:#!/usr/bin/env python3 # encoding=utf-8 from http.server import SimpleHTTPRequestHandler, HTTPServer from datetime import datetime import time class DelayedHTTPRequestHandler(SimpleHTTPRequestHandler): def do_GET(self): current_time = datetime.now() formatted_time = current_time.strftime("%Y-%m-%d %H:%M:%S") print("Time:", formatted_time, "GET request received. Responding after a 30-second delay....") time.sleep(30) # Use the time.sleep function to simulate the processing time of the backend server. SimpleHTTPRequestHandler.do_GET(self) PORT = 8080 server = HTTPServer(("", PORT), DelayedHTTPRequestHandler) print(f"Serving HTTP on 0.0.0.0 port {PORT} (http://0.0.0.0:{PORT}/) ...") server.serve_forever() Após modificar o arquivo de configuração, pressione a tecla
Esc, insira:wqe pressione Enter para salvar e fechar o arquivo.
-
-
Acesse o diretório onde o http_server.py está armazenado e execute o comando a seguir para iniciar o serviço de servidor HTTP:
python3 http_server.pyA resposta a seguir indica que o serviço de back-end do servidor HTTP foi iniciado.
Serving HTTP on 0.0.0.0 port 8080 (http://0.0.0.0:8080/) ...
Adicionar o ECS01 ao grupo de servidores
Faça login no console do ALB.
Na barra de navegação superior, selecione a região onde o grupo de servidores está implantado.
Na página Server Groups, localize o grupo de servidores desejado e clique em Modify Backend Server na coluna Actions.
Na aba Backend Servers, clique em Add Backend Server. No painel Add Backend Server, selecione o ECS01 e clique em Next.
Na etapa Ports/Weights, selecione a instância ECS01, defina a porta como
8080e clique em OK.
Configurar o cliente
-
Faça login no cliente e abra a CLI. Execute o comando a seguir para acessar o servidor de back-end ECS01:
curl http://<domain_name>:80/ -vA resposta a seguir indica que o ALB consegue acessar o serviço de back-end.
* About to connect() to www.example.com port 80 (#0) * Trying 10.X.X.225... * Connected to www.example.com (10.X.X.225) port 80 (#0) > GET / HTTP/1.1 > User-Agent: curl/7.29.0 > Host: www.example.com > Accept: */*O servidor retorna a seguinte resposta.
Serving HTTP on 0.0.0.0 port 8080 (http://0.0.0.0:8080/) ... Time: 2024-02-07 13:57:33 Received a GET request. Responding after a 30-second delay....
Remover o servidor de back-end
Defina o tempo limite do connection draining antes de remover o servidor de back-end.
Faça login no console do ALB.
Na barra de navegação superior, selecione a região onde o grupo de servidores está implantado.
No painel de navegação à esquerda, escolha ALB > Server Groups.
Localize o grupo de servidores desejado e clique em seu ID.
Clique na aba Backend Servers, localize o servidor de back-end ECS01 desejado e clique em Remove na coluna Actions.
Na caixa de diálogo Remove, clique em OK.
Aguardar o connection draining
Os resultados do teste mostram que o cliente recebe uma resposta de erro 500 quando o connection draining timeout definido para o ALB é menor que o backend server processing time.
* About to connect() to www.example.com port 80 (#0)
* Trying 10.X.X.224...
* Connected to www.example.com (10.XX.XX.224) port 80 (#0)
> GET / HTTP/1.1
> User-Agent: curl/7.29.0
> Host: www.example.com
> Accept: */*
>
< HTTP/1.1 500 Internal Server Error
< Date: Wed, 07 Feb 2024 06:02:24 GMT
< Content-Type: text/html
< Content-Length: 186
< Connection: close
< Via: HTTP/1.1 SLB.87
<
<html>
<head><title>500 Internal Server Error</title></head>
<body bgcolor="white">
<center><h1>500 Internal Server Error</h1></center>
<hr><center>nginx</center>
</body>
</html>
* Closing connection 0
Documentação relacionada
Para ativar o connection draining ao criar um grupo de servidores, consulte Criar e gerenciar um grupo de servidores.
Para implementar serviços gradualmente, é possível ativar o recurso de slow start. Para mais informações, consulte Configurar o slow start.
Para saber mais sobre o uso dos protocolos WebSocket e HTTP com o ALB, consulte Adicionar um listener HTTP e Usar o protocolo WebSocket com o ALB para enviar informações em tempo real.