

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

# 为经典负载均衡器配置粘性会话
<a name="elb-sticky-sessions"></a>

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

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

Elastic Load Balancin AWSELB g 会创建一个名为的 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`标志或标志，则也会在 Cookie 上设置该标志或标志。 AWSELB 
+ 如果您在应用程序 cookie 的 `Set-Cookie` 域中有一个尾随分号，负载均衡器会忽略 cookie。

**Topics**
+ [基于持续时间的会话粘性](#enable-sticky-sessions-duration)
+ [应用程序控制的会话粘性](#enable-sticky-sessions-application)

## 基于持续时间的会话粘性
<a name="enable-sticky-sessions-duration"></a>

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

对于 CORS（跨源资源共享）请求，某些浏览器需要 `SameSite=None; Secure` 来启用粘性。在这种情况下，Elastic Load Balancing 会创建第二个粘性 cookie AWSELBCORS，其中包含与原始粘性 cookie 相同的信息以及此属性。`SameSite`客户端会同时收到这两个 Cookie。

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

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

**使用控制台为负载均衡器启用基于持续时间的粘性会话**

1. 打开位于 [https://console.aws.amazon.com/ec2/](https://console.aws.amazon.com/ec2/) 的 Amazon EC2 控制台。

1. 在导航窗格上的 **Load Balancing**（负载均衡）下，选择 **Load Balancers**（负载均衡器）。

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

1. 在**侦听器**选项卡上，选择**管理侦听器**。

1. 在**管理侦听器**页面上，找到要更新的侦听器，然后选择 **Cookie 粘性**下的**编辑**。

1. 在**编辑 Cookie 粘性设置**弹出窗口中，选择**由负载均衡器生成**。

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

1. 选择**保存更改**关闭弹出窗口。

1. 选择**保存更改**返回到负载均衡器详细信息页面。

**要为负载均衡器启用基于持续时间的粘性会话，请使用 AWS CLI**

1. 使用以下 [create-lb-cookie-stickiness-](https://docs.aws.amazon.com/cli/latest/reference/elb/create-lb-cookie-stickiness-policy.html) 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
   ```

1. 使用以下 [set-load-balancer-policiesof-listener](https://docs.aws.amazon.com/cli/latest/reference/elb/set-load-balancer-policies-of-listener.html) 命令为指定的负载均衡器启用会话粘性：

   ```
   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` 选项以列出所有要启用的策略。

1. （可选）使用以下[describe-load-balancers](https://docs.aws.amazon.com/cli/latest/reference/elb/describe-load-balancers.html)命令验证策略是否已启用：

   ```
   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-TLS-1-2-2017-01"
                       ]
                   },
                   ...
               ],            
               ...
               "Policies": {
                   "LBCookieStickinessPolicies": [
                    {
                           "PolicyName": "my-duration-cookie-policy", 
                           "CookieExpirationPeriod": 60
                       }
   
                   ], 
                   "AppCookieStickinessPolicies": [], 
                   "OtherPolicies": [
                       "ELBSecurityPolicy-TLS-1-2-2017-01"
                   ]
               },
               ...
           }
       ]
   }
   ```

## 应用程序控制的会话粘性
<a name="enable-sticky-sessions-application"></a>

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

系统会将以下由后端实例设置的属性发送到 Cookie 中的客户端：`path`、`port`、`domain`、`secure`、`httponly`、`discard`、`max-age`、`expires`、`version`、`comment`、`commenturl` 和 `samesite`。

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

**使用控制台启用应用程序控制的会话粘性**

1. 打开位于 [https://console.aws.amazon.com/ec2/](https://console.aws.amazon.com/ec2/) 的 Amazon EC2 控制台。

1. 在导航窗格上的 **Load Balancing**（负载均衡）下，选择 **Load Balancers**（负载均衡器）。

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

1. 在**侦听器**选项卡上，选择**管理侦听器**。

1. 在**管理侦听器**页面上，找到要更新的侦听器，然后选择 **Cookie 粘性**下的**编辑**。

1. 选择**由应用程序生成**。

1. 对于 **Cookie Name**，键入您的应用程序 Cookie 的名称。

1. 选择**保存更改**。

**要启用应用程序控制的会话粘性，请使用 AWS CLI**

1. 使用以下 [create-app-cookie-stickiness-policy 命令创建应用程序生成的 Cookie 粘性策略](https://docs.aws.amazon.com/cli/latest/reference/elb/create-app-cookie-stickiness-policy.html)：

   ```
   aws elb create-app-cookie-stickiness-policy --load-balancer-name {{my-loadbalancer}} --policy-name {{my-app-cookie-policy}} --cookie-name {{my-app-cookie}}
   ```

1. 使用以下 [set-load-balancer-policiesof-listener](https://docs.aws.amazon.com/cli/latest/reference/elb/set-load-balancer-policies-of-listener.html) 命令为负载均衡器启用会话粘性：

   ```
   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` 选项以列出所有要启用的策略。

1. （可选）使用以下[describe-load-balancers](https://docs.aws.amazon.com/cli/latest/reference/elb/describe-load-balancers.html)命令验证粘性策略是否已启用：

   ```
   aws elb describe-load-balancers --load-balancer-name {{my-loadbalancer}}
   ```

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

   ```
   {
       "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-TLS-1-2-2017-01"
                       ]
                   }, 
                   {
                       "Listener": {
                           "InstancePort": 80, 
                           "LoadBalancerPort": 80, 
                           "Protocol": "TCP", 
                           "InstanceProtocol": "TCP"
                       }, 
                       "PolicyNames": []
                   }
               ],
               ...
               "Policies": {
                   "LBCookieStickinessPolicies": [], 
                   "AppCookieStickinessPolicies": [
                   {
                           "PolicyName": "my-app-cookie-policy", 
                           "CookieName": "my-app-cookie"
                       }
   
                   ], 
                   "OtherPolicies": [
                       "ELBSecurityPolicy-TLS-1-2-2017-01" 
                   ]
               }, 
               ...
           }
       ]
   }
   ```