当您移除某个后端服务器或者后端服务器健康检查异常时,该后端服务器已建立的连接不会立即中断,客户端访问时仍持续有请求转发至这些后端服务器。此时会导致后端服务器的业务长期无法下线或出现请求错误。为了避免该问题,您可以使用ALB的连接优雅中断功能,当移除后端服务器或健康检查异常时,该后端服务器现有连接在一定时间内正常传输,到达中断时间后主动断开连接,保障业务平稳下线。
应用场景
连接优雅中断功能在以下两种场景下使用。
移除后端服务器:移除后端服务器前应设置较长的连接优雅中断超时时间,以便最大程度将连接中的请求处理完成。
健康检查异常:健康检查异常应设置较短的超时时间,以便尽快终止错误连接,避免用户发起请求后才收到连接异常。
由于以上两种场景共用连接优雅中断功能,您需要根据具体业务需求设置合适的优雅中断超时时间。
场景一:移除后端服务器
本文以下图场景为例进行说明。当移除后端服务器ECS01,ALB停止将请求发送到正在移除的后端服务器ECS01,此时ECS01只处理连接中的请求,不接收新的请求。
关闭连接优雅中断功能,ECS01将在处理完连接中的所有请求后关闭会话。
开启连接优雅中断功能并设置中断超时时间:
如果移除的后端服务器ECS01有进行中的请求,ALB会在设置的优雅中断超时时间到达时关闭ECS01上的存量连接会话。
如果移除的后端服务器ECS01中没有进行中的请求且没有活跃连接,ALB将立即完成移除过程,无需等待连接优雅中断超时时间。
如果移除的后端服务器ECS01有正在发送的请求,对应的连接在移除过程结束时被终止,客户端将收到500错误响应(例如,设置的优雅中断超时时间为15秒,但ECS01的请求处理时间为30秒,实际ECS01还未发送完响应之前就会被中断,此时客户端会收到500错误响应)。
说明移除后端服务器ECS01后再次新增ECS01,不会影响移除ECS01后已经开始优雅中断计时的存量连接会话。在存量连接会话关闭前ECS01的状态不会改变(即只处理连接中的请求,不接收新请求)。同时ALB会在设置的优雅中断超时时间到达时,关闭ECS01上的存量连接会话。
移除后端服务器ECS01,开启连接优雅中断功能并设置超时时间后,ECS01的状态流程如下图所示:
场景二:健康检查异常
后端服务器ECS01健康检查异常时,ALB停止将请求发送到ECS01。此时ECS01的状态只处理连接中的请求,不接收新请求。
关闭连接优雅中断功能时,ECS01会一直处于该状态,直到健康检查成功后ECS01才会接收新请求。
开启连接优雅中断并设置优雅中断超时时间:
ALB会在连接优雅中断超时时间到达时,关闭ECS01上的存量连接会话。
如果发生了后端服务器组更新行为(例如更改ECS01的配置),ECS01的连接状态不会改变,即只处理连接中的请求,不接收新请求。即使更新后对应ECS01的健康检查成功,ALB仍旧会在连接优雅中断超时时间到达时,关闭ECS01上的存量连接会话。
说明当ALB在连接优雅中断超时时间到达时,关闭ECS01上的存量连接会话,此时若健康检查正常,ECS01可以正常接收新请求。若健康检查异常,ECS01将不会接收新请求。
配置更新过程中导致健康检查异常,不会触发连接优雅中断。系统只会对检测到后端服务器业务故障导致的健康检查异常,启动连接优雅中断。
后端服务器ECS01健康检查异常时,ECS01的状态流程如下图所示:
您可以根据实际的业务场景配置连接优雅中断。本文以场景一:移除后端服务器为例,通过中断WebSocket会话和HTTP会话进行配置说明。
注意事项
仅标准版和WAF增强版的ALB实例支持连接优雅中断,基础版ALB实例不支持。
函数计算类型的服务器组不支持连接优雅中断。
您可以在使用WebSocket协议时,开启连接优雅中断功能。若您仅在HTTP场景下使用,因HTTP请求有超时和请求个数限制,建议您设置的连接优雅中断超时时间大于ALB的连接请求超时时间(ALB默认设置的优雅中断超时时间,已大于连接请求超时时间),以防HTTP请求异常关闭。关于如何设置连接请求超时时间,请参见添加HTTP监听。
前提条件
您已创建标准版或WAF增强版ALB实例并为该ALB实例创建服务器类型的服务器组。本文以标准版ALB实例为例进行配置说明。具体操作,请参见创建应用型负载均衡和创建和管理服务器组。
您已为该ALB实例配置HTTP监听且设置监听端口为
80
,该监听已关联服务器组。具体操作,请参见添加HTTP监听。您已创建后端服务器ECS01和ECS02实例。具体操作,请参见自定义购买实例。
您已在服务器组中添加ECS02实例,且登录客户端可以访问服务器端ECS02中的服务。具体操作,请参见ALB快速实现IPv4服务的负载均衡和ALB快速实现IPv6服务的负载均衡。
说明本文的客户端以Alibaba Cloud Linux 3.2104 64位操作系统为例,请确保您客户端的操作系统和后端服务器ECS01均安装了Python。如果您的操作系统未安装Python,请参考Python官网进行安装。本文以Python3.x为例进行配置说明。
本文的后端服务器ECS02为业务正常运行的服务器,如果您已有该后端服务器,则无需创建。
配置步骤
开启连接优雅中断并设置中断超时时间后,本文通过演示中断WebSocket会话和HTTP会话,来展现ALB在不同优雅中断状态下对请求的处理效果。
WebSocket会话中断效果
步骤一:开启连接优雅中断
本文前提条件中已创建过服务器组,本步骤仅以编辑服务器组并开启连接优雅中断为例进行配置说明。如果您未创建服务器组,您也可以在创建服务器组时开启连接优雅中断功能。
- 登录应用型负载均衡ALB控制台。
在顶部菜单栏,选择后端服务器组所属的地域。
在左侧导航栏,选择
。在服务器组页面,找到目标服务器组,单击服务器组ID。
在详细信息的基本信息区域,单击编辑基本信息。
在编辑基本信息对话框,单击高级配置,然后开启连接优雅中断。
设置连接优雅中断超时时间为300秒,然后单击保存。
步骤二:结果验证
登录服务器端进行配置
远程登录ECS01实例,具体操作,请参见ECS远程连接方式概述。
执行以下命令创建一个WebSocket文件夹并进入WebSocket目录。
mkdir WebSocket cd WebSocket
执行以下命令安装相关依赖包。
pip install tornado pip install websocket-client
执行以下命令,编辑server.py配置文件。
vim server.py
按
i
键切换至编辑模式,配置以下参数以启动一个WebSocket服务。#!/usr/bin/env python3 # encoding=utf-8 import tornado.websocket import tornado.ioloop import tornado.web from datetime import datetime # WebSocket处理程序 class WebSocketHandler(tornado.websocket.WebSocketHandler): def open(self): current_time = datetime.now() formatted_time = current_time.strftime("%Y-%m-%d %H:%M:%S") print("时间:", formatted_time, "WebSocket连接已打开") def on_message(self, message): current_time = datetime.now() formatted_time = current_time.strftime("%Y-%m-%d %H:%M:%S") print("时间:", formatted_time, "接收到消息:", message) self.write_message("服务器收到了你的消息:" + message) def on_close(self): current_time = datetime.now() formatted_time = current_time.strftime("%Y-%m-%d %H:%M:%S") print("时间:", formatted_time, "WebSocket连接已关闭") # 路由 application = tornado.web.Application([ (r"/websocket", WebSocketHandler), ]) if __name__ == "__main__": print("WebSocket Server Start on 8080 ...") application.listen(8080) tornado.ioloop.IOLoop.current().start()
修改完成后,按下
Esc
键,输入:wq
并回车以保存并关闭配置文件。
进入server.py所在的目录,执行以下命令,启动WebSocket服务。
python3 server.py
当收到以下回复信息时,表示 WebSocket后端服务已开启。
Websocket Server Start on 8080 ...
添加后端服务器ECS01到服务器组
- 登录应用型负载均衡ALB控制台。
在顶部菜单栏,选择后端服务器组所属的地域。
在左侧导航栏,选择
。在服务器组页面,找到目标服务器组,然后在操作列单击编辑后端服务器。
在后端服务器页签,单击添加后端服务器,然后在添加后端服务器面板选择ECS01并单击下一步。
在配置端口和权重配置向导中,勾选ECS01实例并设置端口为
8080
,然后单击确定。
登录客户端进行配置
登录客户端,打开命令行窗口。执行以下命令创建一个WebSocket文件夹并进入WebSocket目录。
mkdir WebSocket cd WebSocket
执行以下命令安装相关依赖包。
pip install websocket-client
执行以下命令,编辑client.py文件。
vim client.py
按
i
键切换至编辑模式,配置以下参数启动一个WebSocket Client访问服务。#!/usr/bin/env python3 # encoding=utf-8 import websocket import time from datetime import datetime def on_message(ws, message): print("接收到服务器的消息:", message) if __name__ == "__main__": ws = websocket.WebSocket() ws.connect("ws://<域名>:80/websocket") # 域名请根据实际情况配置 print("WebSocket连接已打开") try: while True: current_time = datetime.now() formatted_time = current_time.strftime("%Y-%m-%d %H:%M:%S") print("发送时间:", formatted_time) ws.send("Hello, Server!") result = ws.recv() on_message(ws, result) time.sleep(1) except Exception: print("WebSocket连接已关闭")
修改完成后,按下
Esc
键,输入:wq
并回车以保存并关闭配置文件。
进入client.py所在的目录,执行以下命令,访问ECS01服务器端。
python3 client.py
当收到以下回复信息时,表示访问成功。
WebSocket连接已打开 发送时间: 2024-04-28 17:00:53 接收到服务器的消息: 服务器收到了你的消息:Hello, Server! 发送时间: 2024-04-28 17:00:54 接收到服务器的消息: 服务器收到了你的消息:Hello, Server!
此时ECS01服务器端输出以下回复信息。
WebSocket Server Start on 8080 ... 时间: 2024-04-28 17:00:53 WebSocket连接已打开 时间: 2024-04-28 17:00:53 接收到消息: Hello, Server! 时间: 2024-04-28 17:00:54 接收到消息: Hello, Server!
移除后端服务器
需要先设置优雅中断超时时间,再移除后端服务器。
- 登录应用型负载均衡ALB控制台。
在顶部菜单栏,选择后端服务器组所属的地域。
在左侧导航栏,选择
。找到目标服务器组,单击服务器组ID。
单击后端服务器页签,找到目标后端服务器ECS01,然后在操作列单击移除。
在移除服务器对话框中,单击确定。
等待连接优雅中断
本文设置的优雅中断超时时间为300秒,因此通过测试结果可以看到ALB会在移除ECS01后约300秒终止会话。
测试结果中ECS01服务端WebSocket连接打开到关闭的时间差为330秒,优雅中断超时时间为移除后端服务器ECS01至WebSocket连接关闭的时间,约为300秒。
客户端输出以下回复信息。
发送时间: 2024-04-28 17:06:23 接收到服务器的消息: 服务器收到了你的消息:Hello, Server! 发送时间: 2024-04-28 17:06:24 WebSocket连接已关闭
ECS01服务端实例输出以下回复信息。
时间: 2024-04-28 17:06:22 接收到消息: Hello, Server! 时间: 2024-04-28 17:06:23 接收到消息: Hello, Server! 时间: 2024-04-28 17:06:23 WebSocket连接已关闭
HTTP会话中断效果
HTTP场景下优雅中断超时时间、连接请求超时时间以及后端服务器处理时长设置的不同,客户端收到的响应不同。
若优雅中断超时时间<后端服务器处理时长,则ECS01还未发送完响应之前就会被中断,此时客户端会收到500错误响应。
若后端服务器处理时长>连接请求超时时间,则ECS01会响应超时,此时客户端会收到504错误响应。
本文以优雅中断超时时间为15秒,后端服务器处理时长为30秒进行配置说明。在此场景下,ECS01在未发送完响应之前会被中断,客户端会收到500错误响应。
本文通过步骤二设置连接请求超时时间为60秒(默认值),已大于后端服务器处理时长(30秒),因此不会返回504错误响应,而会因为优雅中断超时时间(15秒)小于后端服务器处理时长(30秒)返回500错误响应。
本文通过设置Python代码里的
time.sleep
函数,模拟后端服务器处理时长。
步骤一:开启连接优雅中断
本文前提条件中已创建过服务器组,本步骤仅以编辑服务器组并开启连接优雅中断为例进行配置说明。如果您未创建服务器组,您也可以在创建服务器组时开启连接优雅中断功能。
- 登录应用型负载均衡ALB控制台。
在顶部菜单栏,选择后端服务器组所属的地域。
在左侧导航栏,选择
。在服务器组页面,找到目标服务器组,单击服务器组ID。
在详细信息的基本信息区域,单击编辑基本信息。
在编辑基本信息对话框,单击高级配置,然后开启连接优雅中断。
设置连接优雅中断超时时间为15秒,然后单击保存。
步骤二:设置ALB连接请求超时时间
- 登录应用型负载均衡ALB控制台。
在顶部菜单栏,选择ALB实例所属的地域。
在实例页面,找到目标ALB实例,单击实例ID。
单击监听页签,找到目标HTTP监听,然后单击监听实例ID。
在监听基本信息区域,单击编辑监听。
在编辑监听对话框,单击高级配置后的修改。
修改连接请求超时时间为60秒(默认值),然后单击保存。
步骤三:设置域名解析
实际业务场景中,建议您使用自有域名,通过CNAME解析的方式将自有域名指向ALB实例域名。
在左侧导航栏,选择
在实例页面,复制已创建的ALB实例的DNS名称。
执行以下步骤添加CNAME解析记录。
说明对于非阿里云注册域名,需先将域名添加到云解析控制台,才可以进行域名解析设置。具体操作,请参见域名管理。如果您是阿里云注册的域名,请直接执行以下步骤。
登录域名解析控制台。
在权威域名解析页面,找到目标域名,在操作列单击解析设置。
在解析设置页面,单击添加记录。
在添加记录面板,配置以下信息完成CNAME解析配置,然后单击确定。
配置
说明
记录类型
在下拉列表中选择CNAME。
主机记录
您的域名的前缀。本文输入@。
说明创建域名为根域名时,主机记录为
@
。解析请求来源
选择默认。
记录值
输入域名对应的CNAME地址,即您复制的ALB实例的DNS名称。
TTL
全称Time To Live,表示DNS记录在DNS服务器上的缓存时间,本文使用默认值。
步骤四:结果验证
登录服务器端进行配置
远程登录ECS01实例,具体操作,请参见ECS远程连接方式概述。
执行以下命令创建一个HTTP文件夹并进入HTTP目录。
mkdir http cd http
执行以下命令编辑http_server.py配置文件。
vim http_server.py
按
i
键切换至编辑模式,配置以下参数启动一个http server服务。#!/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("时间:", formatted_time, "收到GET请求,延迟30秒响应....") time.sleep(30) # 设置time.sleep函数,模拟后端服务器处理时长 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()
修改完成后,按下
Esc
键,输入:wq
并回车以保存并关闭配置文件。
进入http_server.py所在的目录,执行以下命令,启动http server服务。
python3 http_server.py
当收到以下回复信息时,表示http server后端服务已开启。
Serving HTTP on 0.0.0.0 port 8080 (http://0.0.0.0:8080/) ...
添加后端服务器ECS01到服务器组
- 登录应用型负载均衡ALB控制台。
在顶部菜单栏,选择后端服务器组所属的地域。
在服务器组页面,找到目标服务器组,然后在操作列单击编辑后端服务器。
在后端服务器页签,单击添加后端服务器,然后在添加后端服务器面板选择ECS01并单击下一步。
在配置端口和权重配置向导中,勾选ECS01实例并设置端口为
8080
,然后单击确定。
登录客户端进行配置
登录客户端,打开命令行窗口。执行以下命令访问后端服务器ECS01。
curl http://<域名>:80/ -v
当收到以下回复信息时,表示ALB可以访问后端服务。
* 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: */*
此时服务端收到如下回复信息。
Serving HTTP on 0.0.0.0 port 8080 (http://0.0.0.0:8080/) ... 时间:2024-02-07 13:57:33 收到Get请求,延迟30秒响应....
移除后端服务器
需要先设置优雅中断超时时间,再移除后端服务器。
- 登录应用型负载均衡ALB控制台。
在顶部菜单栏,选择后端服务器组所属的地域。
在左侧导航栏,选择
。找到目标服务器组,单击服务器组ID。
单击后端服务器页签,找到目标后端服务器ECS01,然后在操作列单击移除。
在移除服务器对话框中,单击确定。
等待连接优雅中断
通过测试结果可以看出,当ALB设置的优雅中断超时时间<后端服务器处理时长时,客户端会收到500错误响应。
* 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
相关文档
当您需要在创建服务器组时开启连接优雅中断功能,请参见创建和管理服务器组。
当您需要实现业务的优雅上线,您可以通过开启慢启动功能。具体操作,请参见通过ALB慢启动实现业务优雅上线。
如果您需要了解WebSocket协议和HTTP协议,请参见添加HTTP监听和ALB使用WebSocket协议实现信息实时推送。