Application Load Balancer 的粘性會話 - Elastic Load Balancing

本文為英文版的機器翻譯版本,如內容有任何歧義或不一致之處,概以英文版為準。

Application Load Balancer 的粘性會話

根據預設,Application Load Balancer 會根據所選的負載平衡演算法,將每個請求獨立路由至註冊的目標。不過,您可以使用粘性會話功能 (也稱為工作階段親和性),讓負載平衡器將使用者的工作階段繫結到特定目標。這樣能確保該工作階段期間所有的使用者請求都能傳送到同一個目標。這功能對於維護狀態資訊以便為用戶端提供持續體驗的伺服器來說很實用。若要使用粘性會話,用戶端必須支援 Cookie。

Application Load Balancer 支援持續時間型 Cookie 和應用程式型 Cookie。粘性會話會在目標群組層級啟用。您可以組合使用持續時間型粘性、應用程式型粘性,以及目標群體之間無粘性。

管理粘性會話的金鑰是決定您的負載平衡器應該持續將使用者請求路由到同一個目標的時間。如果您的應用程式有自己的工作階段 Cookie,則您可以使用應用程式型粘性,負載平衡器工作階段 Cookie 會遵循應用程式的工作階段 Cookie 指定的持續時間。如果您的應用程式沒有自己的工作階段 Cookie,則您可以使用持續時間型粘性,來產生具有指定持續時間的負載平衡器工作階段 Cookie。

系統會使用輪換金鑰來對負載平衡器產生的 Cookie 內容進行加密。您不能解密或修改負載平衡器產生的 Cookie。

對於這兩種粘性類型,Application Load Balancer 會在每次請求後重設其產生的 Cookie 到期時間。如果 Cookie 過期,則工作階段不再具有粘性,用戶端應該從其 Cookie 存放區中刪除該 Cookie。

要求
  • HTTP/HTTPS 負載平衡器。

  • 在各個可用區域內啟動至少一個正常運作的執行個體。

考量事項
  • 如果跨區域負載平衡已停用,便不支援粘性會話。在跨區域負載平衡已停用時,啟用粘性會話的嘗試會失敗。

  • 對於應用程式型 Cookie,必須針對每個目標群組個別指定 Cookie 名稱。但是,對於持續時間型 Cookie,AWSALB 是所有目標群組中唯一使用的名稱。

  • 如果您使用多層 Application Load Balancer,則可以使用應用程式型 Cookie 在所有層級間啟用粘性會話。但是,如果使用持續時間型 Cookie,便只能在一個層上啟用粘性會話,因為 AWSALB 是唯一可用的名稱。

  • 應用程式型粘性不適用於加權目標群組。

  • 如果您有一個轉送規則涉及多個目標群組,且一個或多個目標群組已啟用粘性會話,則您必須啟用目標群組層級的粘性。

  • WebSocket 連接本質上是粘性的。如果用戶端要求連線升級至 WebSockets,則傳回 HTTP 101 狀態碼以接受連線升級的目標就是連線中使用的 WebSockets目標。 WebSockets 升級完成之後,就不會使用以 Cookie 為基礎的黏性。

  • Application Load Balancer 會使用 Cookie 標頭中的 Expires 屬性,而非 Max-Age 屬性。

  • Application Load Balancer 不支援 URL 編碼的 Cookie 值。

持續時間型粘性

持續時間型粘性會使用負載平衡器產生的 Cookie (AWSALB),將請求路由至目標群組中的同一個目標。Cookie 用於將工作階段映射到目標。如果您的應用程式沒有自己的工作階段 Cookie,您可以指定自己的粘性持續時間,並管理負載平衡器應持續地將使用者的請求路由至同一個目標的時間。

負載平衡器首次從用戶端收到請求時,它會將請求路由到目標 (根據所選演算法),並產生一個名為 AWSALB 的 Cookie。它會對所選目標的資訊進行編碼,對 Cookie 進行加密,並在對用戶端的回應中包含 Cookie。負載平衡器產生的 Cookie 自己有 7 天的有效期,且無法設定。

在後續的請求中,用戶端應該包括 AWSALB Cookie。負載平衡器收到來自用戶端包含 Cookie 的請求時,會偵測到此 Cookie,並會將該請求路由至同一個目標。如果 Cookie 存在但無法解碼,或者它參照了已取消註冊或狀況不良的目標,負載平衡器會選取新的目標,並以新目標的相關資訊更新 Cookie。

對於跨源資源共享(CORS)請求,某些瀏覽器需SameSite=None; Secure要啟用粘性。為了支持這些瀏覽器,負載平衡器始終生成第二個粘性 cookieAWSALBCORS,其中包含與原始粘性 cookie 相同的信息以及屬性。SameSite客戶端會收到兩個 cookie,包括非 CORS 請求。

使用主控台啟用持續時間型粘性
  1. 前往 https://console.aws.amazon.com/ec2/ 開啟 Amazon EC2 主控台。

  2. 在導覽窗格的 Load Balancing (負載平衡) 中,選擇 Target Groups (目標群組)

  3. 選擇目標群組的名稱,以開啟其詳細資訊頁面。

  4. 群組詳細資訊索引標籤的屬性區段中,選擇編輯

  5. Edit attributes (編輯屬性) 頁面上,執行下列動作:

    1. 選取粘性

    2. 粘性類型中,選取負載平衡器產生的 Cookie

    3. 針對 Stickiness duration (黏性持續期間),指定介於 1 秒到 7 天之間的值。

    4. 選擇儲存變更

若要啟用以持續時間為基礎的黏性,請使用 AWS CLI

使用 modify-target-group-attributes 命令搭配 stickiness.enabledstickiness.lb_cookie.duration_seconds 屬性。

請使用下列命令啟用持續時間型粘性。

aws elbv2 modify-target-group-attributes --target-group-arn ARN --attributes Key=stickiness.enabled,Value=true Key=stickiness.lb_cookie.duration_seconds,Value=time-in-seconds

輸出內容應如下範例所示。

{ "Attributes": [ ... { "Key": "stickiness.enabled", "Value": "true" }, { "Key": "stickiness.lb_cookie.duration_seconds", "Value": "86500" }, ... ] }

應用程式型粘性

應用程式型粘性可讓您靈活地設定自己的用戶端目標粘性標準。啟用應用程式型粘性後,負載平衡器會根據選擇的演算法,將第一個請求路由到目標群組內的目標。目標預期會設定與負載平衡器上設定的 Cookie 相符的自訂應用程式 Cookie,以啟用粘性。這個自定義 Cookie 可以包括應用程序所需的任何 Cookie 屬性。

Application Load Balancer 從目標收到自訂應用程式 Cookie 後,會自動產生新的加密應用程式 Cookie,以擷取粘性資訊。此負載平衡器產生的應用程式 Cookie 會擷取每個已啟用應用程式型粘性之目標群組的粘性資訊。

負載平衡器產生的應用程式 Cookie 不會複製目標所設定之自訂 Cookie 的屬性。它自己有 7 天的有效期,且無法設定。在對用戶端的回應中,Application Load Balancer 只會驗證在目標群組層級設定之自訂 Cookie 的名稱,而不會驗證自訂 Cookie 的值或到期屬性。只要名稱相符,負載平衡器會在對用戶端待回應中傳送兩個 Cookie,即目標設定的自訂 Cookie 以及負載平衡器產生的應用程式 Cookie。

在後續請求中,用戶端必須傳回這兩個 Cookie 以保持粘性。負載平衡器會解密應用程式 Cookie,並檢查設定的粘性持續時間是否仍然有效。然後,它會使用 Cookie 中的資訊來將請求傳送給目標群組中的同一個目標,以維持粘性。負載平衡器也會將自訂應用程式 Cookie 代理至目標,且不會對其進行檢查或修改。在後續回應中,負載平衡器產生的應用程式 Cookie 到期時間,以及在負載平衡器上設定的粘性持續時間都會重設。為了保持用戶端和目標之間的粘性,Cookie 的到期時間和粘性的持續時間不應結束。

如果目標失敗或運作狀態不佳,負載平衡器會停止路由請求到該目標,並根據選擇的負載平衡演算法選擇運作狀態良好的新目標。負載平衡器會將工作階段視為「粘到」運作狀態良好的新目標,並持續路由請求到運作狀態良好的新目標,即使失敗的目標恢復也是如此。

對於跨來源資源共用 (CORS) 請求,若要啟用粘性,負載平衡器只會在使用者代理程式版本為 Chromium80 或更高版本時,將 SameSite=None; Secure 屬性新增至負載平衡器產生的應用程式 Cookie。

由於大部分瀏覽器會將 Cookie 大小限制在 4K,負載平衡器會將大於 4K 的應用程式 Cookie 分成多個 Cookie 碎片。Application Load Balancer 支援的 Cookie 大小上限為 16K,因此最多會建立 4 個傳送到用戶端的碎片。用戶端看到的應用程式 Cookie 名稱以「AWSALBAPP-」開頭,並包含片段編號。例如,如果 Cookie 大小為 0-4K,則用戶端會看到 AWSALBAPP -0。如果 Cookie 的大小是 4-8k,則客戶端會看到 AWSALBAPP -0 和 AWSALBAPP -1,依此類推。

使用主控台啟用應用程式型粘性
  1. 前往 https://console.aws.amazon.com/ec2/ 開啟 Amazon EC2 主控台。

  2. 在導覽窗格的 Load Balancing (負載平衡) 中,選擇 Target Groups (目標群組)

  3. 選擇目標群組的名稱,以開啟其詳細資訊頁面。

  4. 群組詳細資訊索引標籤的屬性區段中,選擇編輯

  5. Edit attributes (編輯屬性) 頁面上,執行下列動作:

    1. 選取粘性

    2. 粘性類型中,選取應用程式型 Cookie

    3. 針對 Stickiness duration (黏性持續期間),指定介於 1 秒到 7 天之間的值。

    4. 應用程式 Cookie 名稱中,輸入應用程式型 Cookie 的名稱。

      請勿使用 AWSALBAWSALBAPP、或 AWSALBTG 作為 Cookie 名稱;它們預留供負載平衡器使用。

    5. 選擇儲存變更

若要啟用以應用程式為基礎的黏性,請使用 AWS CLI

使用 modify-target-group-attributes 命令搭配以下屬性:

  • stickiness.enabled

  • stickiness.type

  • stickiness.app_cookie.cookie_name

  • stickiness.app_cookie.duration_seconds

請使用下列命令啟用應用程式型粘性。

aws elbv2 modify-target-group-attributes --target-group-arn ARN --attributes Key=stickiness.enabled,Value=true Key=stickiness.type,Value=app_cookie Key=stickiness.app_cookie.cookie_name,Value=my-cookie-name Key=stickiness.app_cookie.duration_seconds,Value=time-in-seconds

輸出內容應如下範例所示。

{ "Attributes": [ ... { "Key": "stickiness.enabled", "Value": "true" }, { "Key": "stickiness.app_cookie.cookie_name", "Value": "MyCookie" }, { "Key": "stickiness.type", "Value": "app_cookie" }, { "Key": "stickiness.app_cookie.duration_seconds", "Value": "86500" }, ... ] }
手動重新平衡

縱向擴展時,如果目標數量大幅增加,則由於粘性,可能會導致負載分配不均衡。在這種情況下,可以使用下列兩個選項重新平衡目標上的負載:

  • 在由應用程式產生的 Cookie 上設定早於目前日期和時間的到期時間。這樣可防止用戶端將 Cookie 傳送至 Application Load Balancer,重新啟動建立粘性的程序。

  • 在負載平衡器的應用程式型粘性組態上設定非常短的持續時間,例如 1 秒。這會強制 Application Load Balancer 重新建立粘性,即使目標所設定的 Cookie 尚未過期。