好的,首先我们有一个运行在 Tomcat 节点上的 java servlet 应用程序。在这之前,我们有 Apache2 使用 ajp 连接器进行负载平衡。
通常,我们会滚动更新错误修正。这需要使用 Apache Jk 状态管理器来禁用节点并将所有新流量重定向到活动节点。这允许用户保留在旧节点上,直到他们注销。经过长时间的等待,我通常可以停止禁用的节点并将更新移入。然后激活该节点并禁用其他节点。
我要解决的问题是防止非活动用户在会话结束后重新连接到禁用的节点。文档中有对这个问题的参考。
关于将激活设置为禁用的最后一点说明:请求附带的会话 ID 作为请求 URL 的一部分 (;jsessionid=...) 或通过 cookie 发送。当使用长时间运行的书签或浏览器时,可能会发送带有指向禁用成员的旧且无效的会话 ID 的请求。由于负载均衡器没有有效会话列表,它会将请求转发给禁用的成员。因此,排水需要的时间比预期的要长。要处理这种情况,您可以向 Web 应用程序添加一个 Servlet 过滤器,该过滤器会检查请求属性 JK_LB_ACTIVATION。该属性包含字符串“ACT”、“DIS”或“STP”之一。如果您检测到“DIS”并且请求的会话不再处于活动状态,重定向的请求将不再携带会话信息,因此负载均衡器不会将其发送给禁用的工作人员。请求属性 JK_LB_ACTIVATION 已在 1.2.32 版本中添加。
我的问题与粗体声明有关。如何防止在重定向中发送 JSESSION ID。
我现在使用的代码只是以无限重定向循环结束。
public final void doGet(HttpServletRequest req, HttpServletResponse res)
throws IOException, ServletException
{
...
String status = (String)req.getAttribute("JK_LB_ACTIVATION");
log.info("Node status " + status);
if("DIS".equals(status)) {
log.info("Status disabled, looking for session ");
Collection<HttpSession> col = TurbineSession.getActiveSessions();
Iterator<HttpSession> it = col.iterator();
boolean found = false;
String requestSession = req.getRequestedSessionId();
sessionSearch: while(it.hasNext()) {
HttpSession session = (HttpSession) it.next();
log.info("Comparing " + requestSession + " to " + session.getId());
if(session.getId().equals(requestSession)) {
found = true;
break sessionSearch;
}
}
if(!found) {
String path = "mypath";
Cookie[] cookies = req.getCookies();
for(Cookie tempCookie : cookies) {
if(requestSession.equals(tempCookie.getValue())) {
// tempCookie.setValue(null);
tempCookie.setMaxAge(0);
// tempCookie.setPath(path);
res.addCookie(tempCookie);
}
}
res.sendRedirect(path);
return;
}
}
...
}
使用 Firebug 检查重定向显示 JSESSIONID 仍包含在重定向中。如何删除它?我所看到的关于删除 cookie 的所有内容似乎都不起作用。