如何疑難排解 Application Load Balancer 工作階段黏性問題?

上次更新日期:2022 年 5 月 2 日

我有一個 Application Load Balancer,使用以持續時間為基礎的黏性以應用程式為基礎的黏性工作階段。負載平衡器設定為將所有使用者工作階段請求路由至相同的目標。不過,使用者工作階段請求會路由至不同的目標。

簡短描述

黏性工作階段使用 cookie 來協助用戶端在 cookie 的生命週期內保持與相同執行個體的連線。使用黏性工作階段設定負載平衡器,可將使用者工作階段繫結至特定的執行個體。這表示在工作階段期間,來自使用者的所有請求都會傳送至相同的執行個體。這種關於連線的假設可能會隨著時間變化而導致不平衡。

如果出現下列情況,黏性工作階段可能會失敗:

  • 註冊的目標未產生 cookie
  • 用戶端未在請求標頭中傳回 cookie
  • cookie 的格式不正確
  • 以持續時間為基礎的工作階段已通過
  • 工作階段請求透過多個負載平衡器傳遞
  • 目標運作狀態變更為「運作狀態不良」
  • AWS 服務已停用的黏性功能

備註:在開始之前,請務必檢閱 Application Load Balancer 的黏性工作階段中的需求注意事項部分。

解決方案

以應用程式為基礎的工作階段黏性

1.    使用負載平衡器檢查 HTTP 錯誤。如需指示,請參閱疑難排解 Application Load Balancer

2.    若要檢查放置在後端執行個體或負載平衡器上的 cookie,請執行類似下列內容的 curl 命令:

備註:將 DNS 名稱替換為您的負載平衡器名稱。

[ec2-user@ip-172-31-22-85 ~]$ curl -vko /dev/null internal-EXAMPLE-ELB-1430759361.eu-central-1.elb.amazonaws.com

備註:Linux curl 公用程式也可以安裝在 Windows OS 上。

範例輸出:

...

< Set-Cookie: PHPSESSID=k0qu6t4e35i4lgmsk78mj9k4a4; path=/

< Set-Cookie:

AWSALBAPP-0=438DC7A50C516D797550CF7DE2A7DBA19D6816D5E6FB20329CD6AEF2B40030B12FF2839757A60E2330136A2182D27D049FB9D887FBFE9E80FB0724130FB3A86A4B0BAC296FDEB9E943EC9272FF52F5A8AEF373DF33;PATH=/

...

3.    若要驗證註冊的目標是否產生應用程式 cookie,請將 HTTP 請求傳送至執行個體 IP 地址,如下所示:

[ec2-user@ip-172-31-22-85 ~]$ curl -vko /dev/null 172.31.30.168

範例輸出:

...

< Set-Cookie: PHPSESSID=5pq74110nuir60kpapj04mglg4; path=/

...

4.    確認已註冊目標所產生的 cookie 名稱與步驟 2 和 3 中負載平衡器上的 cookie 名稱相同。

5.    如果目標產生應用程式 cookie,且負載平衡器產生 AWSALBAPP cookie,請確定用戶端在後續請求中傳送兩個 cookie。如果用戶端無法包含應用程式或 AWSELB cookie,則黏性會失敗。若要驗證用戶端是否同時傳送應用程式和 AWSALBAPP cookie,請在用戶端上進行封包擷取。使用 tcpdumpWireshark 公用程式進行分析,或使用瀏覽器的網頁偵錯工具擷取請求標頭中的 cookie 資訊。

6.    檢查負載平衡器將請求路由至哪個後端執行個體。您可以執行類似下列的指令碼,使用執行個體中繼資料顯示執行個體 ID:

<?php $instance_id =file_get_contents('http://169.254.169.254/latest/meta-data/instance-id');
echo "instance id = " . $instance_id . "\\xA";
?>

7.    檢閱 Elastic Load Balancing 存取記錄,檢查來自同一使用者的請求是否路由至不同的註冊目標。如需指示,請參閱 Application Load Balancer 的存取記錄

8.    驗證已啟用黏性功能之目標群組下所有目標的運作狀態是否良好。如果目標運作狀態變更為「運作狀態不良」,則黏性會中斷,而且負載平衡器會停止將請求路由至該目標。然後負載平衡器會自動選取新的運作狀態良好目標,該目標將會建立黏性工作階段。即使運作狀態為「運作狀態不良」,負載平衡器仍會繼續將請求路由至新目標。如需有關運作狀態檢查的詳細資訊,請參閱目標群組的運作狀態檢查

9.    檢查是否有任何 AWS 服務,例如 Amazon Elastic Kubernetes Service (Amazon EKS),這些服務可能已停用負載平衡器中的黏性功能。使用 API 名稱 “ModifyTargetGroupAttributes” 和屬性 “stickiness.enabled” 查看檢視 CloudTrail 事件

以持續時間為基礎的工作階段黏性

1.    使用負載平衡器 DNS 名稱執行類似下列內容的命令,以檢查回應中是否有 AWSALB cookie:

[ec2-user@ip-172-31-22-85 ~]$ curl -vko /dev/null internal-TESTELB-1430759361.eu-central-1.elb.amazonaws.com

範例輸出:

...< Set-Cookie: 
AWSALB=438DC7A50C516D797550CF7DE2A7DBA19D6816D5E6FB20329CD6AEF2B40030B12FF2839757A60E2330136A2182D27D049FB9D887FBFE9E80FB0724130FB3A86A4B0BAC296FDEB9E943EC9272FF52F5A8AEF373DF33;PATH=/
...

備註:如果回應中沒有 AWSALB cookie,則用戶端和後端執行個體之間沒有黏性。

2.    如果負載平衡器產生 AWSALB cookie,請確定用戶端會在後續請求中傳送此 cookie。如果用戶端未能包含 AWSALB cookie,則黏性功能將無法運作。若要驗證用戶端是否傳送 AWSALB cookie,請在用戶端上進行封包擷取。使用 tcpdumpWireshark 公用程式進行分析,或使用瀏覽器的網頁偵錯工具擷取請求標頭中的 cookie 資訊。

3.    檢查負載平衡器上設定的持續時間。如果 cookie 過期,則在負載平衡器發出新 cookie 之前,用戶端工作階段將不會再保留在註冊的目標上。

4.    如果您的請求透過多個負載平衡器傳遞,請確認僅在一個負載平衡器上啟用黏性功能。如果有多個負載平衡器產生 cookie,則負載平衡器會取代原始 cookie,且黏性功能會失敗。

若為 Classic Load Balancer,請參閱如何疑難排解 Classic Load Balancer 工作階段黏性功能?