我在负载均衡器后面有两台物理 Apache 服务器。负载均衡器应该设置为在第一次请求后始终将用户发送到同一台物理服务器,以保留会话。
在我们向设置中添加 SSL 之前,这对于我们的 Web 应用来说运行良好。现在用户可以成功登录并查看主页,但单击任何其他内部链接都会让用户直接退出。我追溯到这个问题,虽然初始身份验证由服务器 1 执行,但单击内部链接会导致请求发送到服务器 2。服务器 2 不与服务器 1 共享会话,用户被踢出。
我该如何修复它?
我需要在两台服务器之间共享会话吗?如果需要,您能给我提供一份好的指南吗?
谢谢。
答案1
如果您希望在负载均衡器中实现会话粘性,则必须终止负载均衡器上的 SSL。这意味着您必须将 SSL 证书安装到负载均衡器中。
另一种解决方案是将负载均衡器配置为使用 SSL(HTTPS)的源 IP 粘性。
第三种解决方案是将会话保存在公共数据库中(例如 memcached、SQL 数据库)。对于 .NET,请参阅:http://support.microsoft.com/kb/317604 对于 PHP,请参阅:http://kevin.vanzonneveld.net/techblog/article/enhance_php_session_management/
答案2
您的负载均衡器可能会使用 HTTP 标头数据来确定将您的用户发送到哪个框(而不是通过 IP 地址判断)。
[如果您可以告诉我们您正在使用哪种类型的负载均衡器,有关配置它的有用信息可能会发布在这里:-)]
除了重新配置负载均衡器之外,您可能还需要考虑在两台服务器之间共享会话。您可以通过以下方式执行此操作:
- 将会话放在两台服务器上安装的 NFS 共享上
(只要 NFS 服务器不消失,它就是传统且相当可靠的)。 - 如果您使用 PHP,请使用 session_mysql、session_pgsql 或任何其他可用的会话处理程序。
(与后备存储一样可靠)
(共享会话的优点是您的服务器提供无缝冗余:如果服务器 1 因维护而停机,服务器 2 可以接管其所有会话,而无需强迫用户再次登录)
答案3
听起来(如果没有更多信息,很难确定)您的负载均衡器 Apache 配置中没有完全实现持久性。看一下负载均衡器粘性Apache 文档中的mod_proxy_balancer。
平衡器支持粘性。当请求被代理到某个后端时,来自同一用户的所有后续请求都应被代理到同一后端。许多负载平衡器通过将客户端 IP 地址映射到后端的表来实现此功能。这种方法对客户端和后端都是透明的,但也存在一些问题:如果客户端本身隐藏在代理后面,则负载分配不均;如果客户端使用在会话期间发生变化的动态 IP 地址,则会出现粘性错误;如果映射表溢出,则粘性会丧失。
mod_proxy_balancer 模块通过两种替代方法实现粘性:cookie 和 URL 编码。cookie 可以由后端提供,也可以由 Apache Web 服务器本身提供。URL 编码通常在后端完成。
以下示例取自该文档:
Header add Set-Cookie "ROUTEID=.%{BALANCER_WORKER_ROUTE}e; path=/" env=BALANCER_ROUTE_CHANGED
<Proxy balancer://mycluster>
BalancerMember http://192.168.1.50:80 route=1
BalancerMember http://192.168.1.51:80 route=2
ProxySet stickysession=ROUTEID
</Proxy>
ProxyPass /test balancer://mycluster
答案4
您说负载平衡器设置为倾向于将用户的第一个请求发送到同一台服务器 - 听起来这在 SSL 上不起作用,但在 SSL 之前可以正常工作。听起来像是负载平衡器的配置问题;您能提供关于它是什么以及如何配置的信息吗?