當您移除某個後端伺服器或者後端伺服器健全狀態檢查異常時,該後端伺服器已建立的串連不會立即中斷,用戶端訪問時仍持續有請求轉寄至這些後端伺服器。此時會導致後端伺服器的業務長期無法下線或出現請求錯誤。為了避免該問題,您可以使用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執行個體不支援。
Function Compute類型的伺服器組不支援串連優雅中斷。
您可以在使用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協議實現資訊即時推送。