为经典负载均衡器配置粘性会话 - Elastic Load Balancing
Amazon Web Services 文档中描述的 Amazon Web Services 服务或功能可能因区域而异。要查看适用于中国区域的差异,请参阅 中国的 Amazon Web Services 服务入门 (PDF)

本文属于机器翻译版本。若本译文内容与英语原文存在差异,则一律以英文原文为准。

为经典负载均衡器配置粘性会话

默认情况下,经典负载均衡器会将每项请求单独路由到负载最小的已注册实例。但是,您可以使用粘性会话 功能 (也称为会话关联),使负载均衡器能够将用户会话绑定到特定的实例。这可确保在会话期间将来自用户的所有请求发送到相同的实例中。

管理粘性会话的关键是确定负载均衡器一致地将用户请求路由到相同实例的时间长短。如果您的应用程序具有自己的会话 Cookie,则可以配置 Elastic Load Balancing,以便会话 Cookie 遵循应用程序会话 Cookie 指定的持续时间。如果您的应用程序没有自己的会话信息记录程序,您可以配置 Elastic Load Balancing,以通过指定您自己的粘性持续时间来创建会话信息记录程序。

Elastic Load Balancing 将创建一个名为 AWSELB 的 Cookie,用于将会话映射到实例。

要求
  • HTTP/HTTPS 负载均衡器。

  • 每个可用区内至少有一个运行状况良好的实例。

兼容性
  • Cookie 路径属性的 RFC 允许使用下划线。不过,Elastic Load Balancing URI 将下划线字符编码为 %5F,因为某些浏览器(如 Internet Explorer 7)规定下划线的 URI 编码为 %5F。由于可能影响当前运行的浏览器,Elastic Load Balancing 继续对下划线字符进行 URI 编码。例如,如果 Cookie 具有属性 path=/my_path,则 Elastic Load Balancing 在转发请求中将此属性更改为 path=/my%5Fpath

  • 您不能对基于持续时间的会话粘性 Cookie 设置 secure 标志或 HttpOnly 标志。不过,这些 Cookie 不包含敏感数据。请注意,如果对应用程序控制的会话粘性 Cookie 设置 secure 标志或 HttpOnly 标志,则还会对 AWSELB Cookie 设置此类标志。

  • 如果您在应用程序 cookie 的 Set-Cookie 域中有一个尾随分号,负载均衡器会忽略 cookie。

基于持续时间的会话粘性

负载均衡器会使用一个特殊 Cookie(即 AWSELB)来跟踪发送到每个侦听器的每个请求的实例。在负载均衡器收到请求时,它首先会检查并查看请求中是否存在这个 Cookie。如果是这样的话,该请求会发送到 Cookie 中指定的实例。如果没有 Cookie,负载均衡器会根据现有的负载均衡算法选择一个实例。响应中会插入 Cookie,从而将同一用户发出的后续请求绑定到该实例中。粘性策略配置会定义 Cookie 的过期时间,从而确定每个 Cookie 的有效持续时间。负载均衡器不会刷新 Cookie 的过期时间,并且在使用 Cookie 前不会检查它是否已过期。Cookie 过期后,会话将不再具有粘性。一旦 Cookie 过期,客户端就会从其 Cookie 存储中删除 Cookie。

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

如果实例失败或者实例运行状况不佳,负载均衡器会停止将请求路由到该实例,并根据现有负载均衡算法来选择新的运行状况良好的实例。此时会将请求路由到新实例,就像没有 Cookie 一样,会话不再具有粘性。

如果客户端切换到带其他后端端口的侦听器,粘性将丢失。

New EC2 experience
使用控制台为负载均衡器启用基于持续时间的粘性会话
  1. 通过以下网址打开 Amazon EC2 控制台:https://console.aws.amazon.com/ec2/

  2. 在导航窗格上的 Load Balancing(负载均衡)下,选择 Load Balancers(负载均衡器)。

  3. 选择负载均衡器的名称以打开其详细信息页面。

  4. 侦听器选项卡上,选择管理侦听器

  5. 管理侦听器页面上,找到要更新的侦听器,然后选择 Cookie 粘性下的编辑

  6. 选择由负载均衡器生成

  7. (可选)对于有效期,键入 Cookie 有效期(以秒为单位)。如果不指定有效期,只要浏览器会话不中断,粘性会话就会持续。

  8. 选择保存更改

Old EC2 experience
使用控制台为负载均衡器启用基于持续时间的粘性会话
  1. 通过以下网址打开 Amazon EC2 控制台:https://console.aws.amazon.com/ec2/

  2. 在导航窗格上的 Load Balancing(负载均衡)下,选择 Load Balancers(负载均衡器)。

  3. 选择您的负载均衡器。

  4. Description 选项卡上,选择 Edit stickiness

  5. Edit stickiness 页面上,选择 Enable load balancer generated cookie stickiness

  6. (可选) 对于 Expiration Period,键入 Cookie 有效期 (以秒为单位)。如果不指定有效期,只要浏览器会话不中断,粘性会话就会持续。

  7. 选择 Save

使用 Amazon CLI 为负载均衡器启用基于持续时间的粘性会话
  1. 使用以下 create-lb-cookie-stickiness-policy 命令创建负载均衡器生成的 Cookie 粘性策略,Cookie 有效期为 60 秒:

    aws elb create-lb-cookie-stickiness-policy --load-balancer-name my-loadbalancer --policy-name my-duration-cookie-policy --cookie-expiration-period 60
  2. 使用以下 set-load-balancer-policies-of-listener 命令为指定的负载均衡器启用会话粘性:

    aws elb set-load-balancer-policies-of-listener --load-balancer-name my-loadbalancer --load-balancer-port 443 --policy-names my-duration-cookie-policy
    注意

    set-load-balancer-policies-of-listener 命令替换与指定负载均衡器端口关联的当前策略集。每次使用此命令时,请指定 --policy-names 选项以列出所有要启用的策略。

  3. (可选)使用以下 describe-load-balancers 命令验证是否已启用策略:

    aws elb describe-load-balancers --load-balancer-name my-loadbalancer

    响应包含以下信息,表明已在指定端口上为侦听器启用策略:

    { "LoadBalancerDescriptions": [ { ... "ListenerDescriptions": [ { "Listener": { "InstancePort": 443, "SSLCertificateId": "arn:aws:iam::123456789012:server-certificate/my-server-certificate", "LoadBalancerPort": 443, "Protocol": "HTTPS", "InstanceProtocol": "HTTPS" }, "PolicyNames": [ "my-duration-cookie-policy", "ELBSecurityPolicy-2016-08" ] }, ... ], ... "Policies": { "LBCookieStickinessPolicies": [ { "PolicyName": "my-duration-cookie-policy", "CookieExpirationPeriod": 60 } ], "AppCookieStickinessPolicies": [], "OtherPolicies": [ "ELBSecurityPolicy-2016-08" ] }, ... } ] }

应用程序控制的会话粘性

负载均衡器使用一个特殊的 Cookie 将会话和处理初始请求的实例相关联,但会沿用策略配置中指定的应用程序 Cookie 的使用时间限制。负载均衡器只会在应用程序响应中包含新的应用程序信息记录程序时,才会插入新的粘性信息记录程序。负载均衡器粘性信息记录程序不会根据每项请求进行更新。如果应用程序信息记录程序被明确删除或过期,会话便会停止粘着,直至发布新的应用程序信息记录程序为止。

系统会将以下由后端实例设置的属性发送到 Cookie 中的客户端:pathportdomainsecurehttponlydiscardmax-ageexpiresversioncommentcommenturlsamesite

如果实例失败或者实例运行状况不佳,负载均衡器会停止将请求路由到该实例,并根据现有负载均衡算法来选择新的运行状况良好的实例。现在,负载均衡器将会话视为“附加”到新的正常运行实例,并继续将请求路由至该实例,即使之前失败的实例已恢复正常运行。

New EC2 experience
使用控制台启用应用程序控制的会话粘性
  1. 通过以下网址打开 Amazon EC2 控制台:https://console.aws.amazon.com/ec2/

  2. 在导航窗格上的 Load Balancing(负载均衡)下,选择 Load Balancers(负载均衡器)。

  3. 选择负载均衡器的名称以打开其详细信息页面。

  4. 侦听器选项卡上,选择管理侦听器

  5. 管理侦听器页面上,找到要更新的侦听器,然后选择 Cookie 粘性下的编辑

  6. 选择由应用程序生成

  7. 对于 Cookie Name,键入您的应用程序 Cookie 的名称。

  8. 选择保存更改

Old EC2 experience
使用控制台启用应用程序控制的会话粘性
  1. 通过以下网址打开 Amazon EC2 控制台:https://console.aws.amazon.com/ec2/

  2. 在导航窗格上的 Load Balancing(负载均衡)下,选择 Load Balancers(负载均衡器)。

  3. 选择您的负载均衡器。

  4. Description 选项卡上,选择 Edit stickiness

  5. Edit stickiness 页面中,选择 Enable application generated cookie stickiness

  6. 对于 Cookie Name,键入您的应用程序 Cookie 的名称。

  7. 选择 Save

使用 Amazon CLI 启用应用程序控制的会话粘性
  1. 使用以下 create-app-cookie-stickiness-policy 命令创建应用程序生成的 Cookie 粘性策略:

    aws elb create-app-cookie-stickiness-policy --load-balancer-name my-loadbalancer --policy-name my-app-cookie-policy --cookie-name my-app-cookie
  2. 使用以下 set-load-balancer-policies-of-listener 命令为负载均衡器启用会话粘性:

    aws elb set-load-balancer-policies-of-listener --load-balancer-name my-loadbalancer --load-balancer-port 443 --policy-names my-app-cookie-policy
    注意

    set-load-balancer-policies-of-listener 命令替换与指定负载均衡器端口关联的当前策略集。每次使用此命令时,请指定 --policy-names 选项以列出所有要启用的策略。

  3. (可选)使用以下 describe-load-balancers 命令验证是否已启用粘性策略:

    aws elb describe-load-balancers --load-balancer-name my-loadbalancer
  4. 响应包含以下信息,表明已在指定端口上为侦听器启用策略:

    { "LoadBalancerDescriptions": [ { ... "ListenerDescriptions": [ { "Listener": { "InstancePort": 443, "SSLCertificateId": "arn:aws:iam::123456789012:server-certificate/my-server-certificate", "LoadBalancerPort": 443, "Protocol": "HTTPS", "InstanceProtocol": "HTTPS" }, "PolicyNames": [ "my-app-cookie-policy", "ELBSecurityPolicy-2016-08" ] }, { "Listener": { "InstancePort": 80, "LoadBalancerPort": 80, "Protocol": "TCP", "InstanceProtocol": "TCP" }, "PolicyNames": [] } ], ... "Policies": { "LBCookieStickinessPolicies": [], "AppCookieStickinessPolicies": [ { "PolicyName": "my-app-cookie-policy", "CookieName": "my-app-cookie" } ], "OtherPolicies": [ "ELBSecurityPolicy-2016-08" ] }, ... } ] }