全部產品
Search
文件中心

Server Load Balancer:通過ALB串連優雅中斷實現業務平穩下線

更新時間:Nov 15, 2024

當您移除某個後端伺服器或者後端伺服器健全狀態檢查異常時,該後端伺服器已建立的串連不會立即中斷,用戶端訪問時仍持續有請求轉寄至這些後端伺服器。此時會導致後端伺服器的業務長期無法下線或出現請求錯誤。為了避免該問題,您可以使用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會話中斷效果

步驟一:開啟串連優雅中斷

本文前提條件中已建立過伺服器組,本步驟僅以編輯服務器組並開啟串連優雅中斷為例進行配置說明。如果您未建立伺服器組,您也可以在建立伺服器組時開啟串連優雅中斷功能。

  1. 登入應用型負載平衡ALB控制台
  2. 在頂部功能表列,選擇後端伺服器組所屬的地區。

  3. 在左側導覽列,選擇應用型負載平衡ALB > 伺服器組

  4. 伺服器組頁面,找到目標伺服器組,單擊伺服器組ID。

  5. 詳細資料基本資料地區,單擊編輯基本資料

  6. 編輯基本資料對話方塊,單擊進階配置,然後開啟串連優雅中斷

  7. 設定串連優雅中斷逾時時間300秒,然後單擊儲存

步驟二:結果驗證

登入伺服器端進行配置

  1. 遠程登入ECS01執行個體,具體操作,請參見ECS遠端連線方式概述

  2. 執行以下命令建立一個WebSocket檔案夾並進入WebSocket目錄。

    mkdir WebSocket
    cd WebSocket
  3. 執行以下命令安裝相關依賴包。

    pip install tornado
    pip install websocket-client
  4. 執行以下命令,編輯server.py設定檔。

    vim server.py
    1. 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()
      
    2. 修改完成後,按下Esc鍵,輸入:wq並斷行符號以儲存並關閉設定檔。

  5. 進入server.py所在的目錄,執行以下命令,啟動WebSocket服務。

    python3 server.py

    當收到以下回複資訊時,表示 WebSocket後端服務已開啟。

    Websocket Server Start on 8080 ...

添加後端伺服器ECS01到伺服器組

  1. 登入應用型負載平衡ALB控制台
  2. 在頂部功能表列,選擇後端伺服器組所屬的地區。

  3. 在左側導覽列,選擇應用型負載平衡ALB > 伺服器組

  4. 伺服器組頁面,找到目標伺服器組,然後在操作列單擊編輯後端伺服器

  5. 後端伺服器頁簽,單擊添加後端伺服器,然後在添加後端伺服器面板選擇ECS01並單擊下一步

  6. 配置連接埠和權重設定精靈中,勾選ECS01執行個體並設定連接埠為8080,然後單擊確定

登入用戶端進行配置

  1. 登入用戶端,開啟命令列視窗。執行以下命令建立一個WebSocket檔案夾並進入WebSocket目錄。

    mkdir WebSocket
    cd WebSocket
  2. 執行以下命令安裝相關依賴包。

    pip install websocket-client
  3. 執行以下命令,編輯client.py檔案。

    vim client.py
    1. 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串連已關閉")
      
    2. 修改完成後,按下Esc鍵,輸入:wq並斷行符號以儲存並關閉設定檔。

  4. 進入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!

移除後端伺服器

重要

需要先設定優雅中斷逾時時間,再移除後端伺服器。

  1. 登入應用型負載平衡ALB控制台
  2. 在頂部功能表列,選擇後端伺服器組所屬的地區。

  3. 在左側導覽列,選擇應用型負載平衡ALB > 伺服器組

  4. 找到目標伺服器組,單擊伺服器組ID。

  5. 單擊後端伺服器頁簽,找到目標後端伺服器ECS01,然後在操作列單擊移除

  6. 移除伺服器對話方塊中,單擊確定。

等待串連優雅中斷

本文設定的優雅中斷逾時時間為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函數,類比後端伺服器處理時間長度

步驟一:開啟串連優雅中斷

本文前提條件中已建立過伺服器組,本步驟僅以編輯服務器組並開啟串連優雅中斷為例進行配置說明。如果您未建立伺服器組,您也可以在建立伺服器組時開啟串連優雅中斷功能。

  1. 登入應用型負載平衡ALB控制台
  2. 在頂部功能表列,選擇後端伺服器組所屬的地區。

  3. 在左側導覽列,選擇應用型負載平衡ALB > 伺服器組

  4. 伺服器組頁面,找到目標伺服器組,單擊伺服器組ID。

  5. 詳細資料基本資料地區,單擊編輯基本資料

  6. 編輯基本資料對話方塊,單擊進階配置,然後開啟串連優雅中斷

  7. 設定串連優雅中斷逾時時間15秒,然後單擊儲存

步驟二:設定ALB串連請求逾時時間

  1. 登入應用型負載平衡ALB控制台
  2. 在頂部功能表列,選擇ALB執行個體所屬的地區。

  3. 執行個體頁面,找到目標ALB執行個體,單擊執行個體ID。

  4. 單擊監聽頁簽,找到目標HTTP監聽,然後單擊監聽執行個體ID。

  5. 監聽基本資料地區,單擊編輯監聽

  6. 編輯監聽對話方塊,單擊進階配置後的修改

  7. 修改串連請求逾時時間60秒(預設值),然後單擊儲存

步驟三:設定網域名稱解析

實際業務情境中,建議您使用自有網域名稱,通過CNAME解析的方式將自有網域名稱指向ALB執行個體網域名稱。

  1. 在左側導覽列,選擇應用型負載平衡 ALB > 執行個體

  2. 執行個體頁面,複製已建立的ALB執行個體的DNS名稱。

  3. 執行以下步驟添加CNAME解析記錄。

    說明

    對於非阿里雲註冊網域名稱,需先將網域名稱添加到雲解析控制台,才可以進行網域名稱解析設定。具體操作,請參見網域名稱管理。如果您是阿里雲註冊的網域名稱,請直接執行以下步驟。

    1. 登入網域名稱解析控制台

    2. 權威網域名稱解析頁面,找到目標網域名稱,在操作列單擊解析設定

    3. 解析設定頁面,單擊添加記錄

    4. 添加記錄面板,配置以下資訊完成CNAME解析配置,然後單擊確定

      配置

      說明

      記錄類型

      在下拉式清單中選擇CNAME

      主機記錄

      您的網域名稱的首碼。本文輸入@

      說明

      建立網域名稱為根網域名稱時,主機記錄為@

      解析請求來源

      選擇預設。

      記錄值

      輸入欄位名對應的CNAME地址,即您複製的ALB執行個體的DNS名稱。

      TTL

      全稱Time To Live,表示DNS記錄在DNS伺服器上的緩衝時間,本文使用預設值。

步驟四:結果驗證

登入伺服器端進行配置

  1. 遠程登入ECS01執行個體,具體操作,請參見ECS遠端連線方式概述

  2. 執行以下命令建立一個HTTP檔案夾並進入HTTP目錄。

    mkdir http
    cd http
  3. 執行以下命令編輯http_server.py設定檔。

    vim http_server.py
    1. 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()
      
    2. 修改完成後,按下Esc鍵,輸入:wq並斷行符號以儲存並關閉設定檔。

  4. 進入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到伺服器組

  1. 登入應用型負載平衡ALB控制台
  2. 在頂部功能表列,選擇後端伺服器組所屬的地區。

  3. 伺服器組頁面,找到目標伺服器組,然後在操作列單擊編輯後端伺服器

  4. 後端伺服器頁簽,單擊添加後端伺服器,然後在添加後端伺服器面板選擇ECS01並單擊下一步

  5. 配置連接埠和權重設定精靈中,勾選ECS01執行個體並設定連接埠為8080,然後單擊確定

登入用戶端進行配置

  1. 登入用戶端,開啟命令列視窗。執行以下命令訪問後端伺服器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秒響應....

移除後端伺服器

重要

需要先設定優雅中斷逾時時間,再移除後端伺服器。

  1. 登入應用型負載平衡ALB控制台
  2. 在頂部功能表列,選擇後端伺服器組所屬的地區。

  3. 在左側導覽列,選擇應用型負載平衡ALB > 伺服器組

  4. 找到目標伺服器組,單擊伺服器組ID。

  5. 單擊後端伺服器頁簽,找到目標後端伺服器ECS01,然後在操作列單擊移除

  6. 移除伺服器對話方塊中,單擊確定。

等待串連優雅中斷

通過測試結果可以看出,當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

相關文檔