我们有一个使用 sso 来登录用户的 Drupal 应用程序。
我们正在使用 AWS 经典负载均衡器(ELB),AWS 告诉我们 ELB 上没有会话持久性。
我想弄清楚的是 cookie 如何在传统负载均衡器上以非持久性的方式工作。
example.com DNS 指向 ELB。池中有 2 个服务器:Server1 和 Server2
我们希望的是,如果用户http://example.com/user/12345/
在服务器 1 上点击他们的主页(如果他们尚未登录),则将重定向到 sso 页面http://example.com/user/login/sso
,自动登录并获取 cookie SESS<hexnumber>
,然后重定向回http://example.com/user/12345/
我们不允许添加任何会话服务器(redis),如何保证它们在两次重定向中都停留在服务器 1 上。
据我所知,每次访问“example.com”时,用户最终可能会进入服务器 1 或服务器 2。
我的问题:
如果他们在服务器 1 上获取 cookie,然后被重定向到服务器 2,那么服务器 2 如何知道服务器 1 上已经为该用户分配了 cookie?
我似乎在自寻死路。过去在使用没有会话持久性的 LB 进行此类设置时,我们使用 redis 服务器来保存会话,并且每个请求都会查看 redis 服务器以获取会话信息。
答案1
Cookie 是在浏览器中设置的,而不是在服务器中设置的。它仅限于某个域,并且(可选)URL 中的特定路径,因此只要两个服务器都由同一个域访问,Cookie 就会存在。
如果 cookie 指向会话,则服务器 1 和服务器 2 都必须以某种方式访问该会话。如果服务器之间无法共享会话,则需要强制用户坚持使用特定服务器。这可以通过 DNS 和少量 URL 重写魔法轻松实现:
- www.example.com 指向两个服务器。
- www1.example.com 仅指向 server1
- www2.example.com 仅指向 server2
使用一组简单的重写规则和 cookie,就可以将用户锁定到特定的服务器,确保他的会话持续存在。
以下是更多详细信息。
DNS:
- example.com A 1.1.1.1,A 2.2.2.2
- www.example.com CNAME example.com
- www1.example.com A 1.1.1.1
- www2.example.com A 2.2.2.2
重写规则:
- 持久性 cookie:“后端”
- 初始连接:未定义“backend”,将“backend”设置为 www1 或 www2,具体取决于哪个服务器已应答并重定向到该服务器。必须将 cookie 设置为域“example.com”,这样它将在 www1 和 www2 上加载
- 如果定义了“后端”,请确保其值与服务器实例匹配,并在必要时进行重定向。
- 确保会话 cookie 在服务器的完整域名中定义 - 即 www1.example.com 或 www2.example.com
重写逻辑将在 Web 服务器本身中定义。所有现代 Web 服务器都具有功能强大的重写语言,完全能够实现此功能。
答案2
如果您不能使用像 Elasticache Redis 这样的会话管理数据库(仅用于会话的 Redis 每月费用不应超过 15 美元),那么下一个最佳选择是在 ELB 上启用粘性会话;
https://docs.aws.amazon.com/elasticloadbalancing/latest/classic/elb-sticky-sessions.html
这将强制用户在整个会话期间转到相同的后端节点。“负载平衡器生成的 cookie”的生命周期为 900 秒应该足够了,但您可以对此进行调整。