首先,此应用程序在非集群环境中运行良好。
我们遇到的问题是,ELB 在会话期间首先路由到集群中的一台服务器,然后再路由到第二台服务器。第二台服务器找不到会话。例如
- iOS 应用程序将登录调用传递给 Glassfish 4 服务器集群(我们使用 oAuth/Facebook 令牌,因此没有 Glassish 安全领域)。
- Amazon Elastic Load Balancer (ELB) 发送到服务器 1。
- 会话经过身份验证,用户登录,会话 cookie 传回应用程序。
- 应用程序立即发送另一个需要身份验证的请求(这是一个有效的会话)。
- ELB 决定将请求发送到服务器 2
- 在我们的身份验证 servlet 过滤器中,服务器 2 找不到使用 cookie 传入的 id 的会话
- servlet 表示用户未通过身份验证并且调用失败。
我们的代码非常典型地用于查找会话(如果没有会话立即返回失败):
HttpSession session = req.getSession(false);
//psuedocode
if session == null then session not authenticated log and return
else session authenticated, log and return
如果第二个呼叫被路由到与登录相同的服务器,则第二个呼叫工作正常。每当呼叫(无论是第二个、第三个、第四个,等等)转到第二个服务器时,身份验证都会失败,因为它在第二个服务器上找不到会话。
我正在寻找是否有人遇到过这样的事情以及您是如何解决这个问题的。在 ELB 上使用粘性会话更好,还是使用 JK 或 AJP 的 Apache Web 服务器是更好的选择?