Application Load Balancer 的粘性会话 - Elastic Load Balancing
AWS 文档中描述的 AWS 服务或功能可能因区域而异。要查看适用于中国区域的差异,请参阅中国的 AWS 服务入门

Application Load Balancer 的粘性会话

默认情况下,Application Load Balancer 会根据选定负载均衡算法将每项请求单独路由到已注册的目标。但是,您可以使用粘性会话功能(也称为会话关联),使负载均衡器能够将用户会话绑定到特定的目标。这可确保在会话期间将来自用户的所有请求发送到同一目标中。对于维护状态信息以便向客户端提供持续体验的服务器来说,此功能很有用。要使用粘性会话,客户端必须支持 Cookie。

Application Load Balancer 支持基于持续时间的 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。

在后续请求中,客户端应包含 AWSALB Cookie。当负载均衡器收到来自包含 Cookie 的客户端的请求时,它会检测到该请求并将请求路由到同一目标。如果 cookie 存在但无法解码,或者它指的是已取消注册或不正常的目标,则负载均衡器会选择一个新目标并使用有关新目标的信息更新 cookie。

对于跨源资源共享 (CORS) 请求,某些浏览器需要 SameSite=None; Secure 来启用粘性。在这种情况下,负载均衡器会生成第二个粘性 Cookie(即 AWSALBCORS),该 Cookie 中包含原始粘性 Cookie 中的信息加上此 SameSite 属性。客户端会同时收到这两个 Cookie。

使用控制台启用基于持续时间的粘性

  1. 通过以下网址打开 Amazon EC2 控制台:https://console.aws.amazon.com/ec2/

  2. 在导航窗格上的 Load Balancing(负载均衡)下,选择 Target Groups(目标组)。

  3. 选择目标组的名称以打开其详细信息页面。

  4. 组详细信息选项卡的属性部分中,选择编辑

  5. Edit attributes 页上,执行以下操作:

    1. 选择粘性

    2. 对于 Stickiness type(Stickiness 类型),请选择 Load balancer generated cookie(负载均衡器生成的 Cookie)。

    3. 对于 Stickiness duration,指定一个介于 1 秒和 7 天之间的值。

    4. 选择保存更改

使用 AWS CLI 启用基于持续时间的粘性

使用带 stickiness.enabledstickiness.lb_cookie.duration_seconds 属性的 modify-target-group-attributes 命令。

使用以下命令启用基于持续时间的粘性。

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 支持最大 16K 的 Cookie,因此最多可以创建 4 个分片发送给客户端。客户端看到的应用程序 Cookie 名称以“AWSALBAPP-”开头,并包含片段编号。例如,如果 Cookie 的大小为 0-4K,客户端看到的名称将是 AWSALBAPP-0。如果 Cookie 的大小为 4-8k,客户端看到的名称将是 AWSALBAPP-0 和 AWSALBAPP-1,依此类推。

使用控制台启用基于应用程序的粘性

  1. 通过以下网址打开 Amazon EC2 控制台:https://console.aws.amazon.com/ec2/

  2. 在导航窗格上的 Load Balancing(负载均衡)下,选择 Target Groups(目标组)。

  3. 选择目标组的名称以打开其详细信息页面。

  4. 组详细信息选项卡的属性部分中,选择编辑

  5. Edit attributes 页上,执行以下操作:

    1. 选择粘性

    2. 对于 Stickiness type(Stickiness 类型),请选择 Application-based cookie(基于应用程序的 Cookie)。

    3. 对于 Stickiness duration,指定一个介于 1 秒和 7 天之间的值。

    4. 对于 App cookie name(应用程序 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 尚未过期。