如何在重定向Apache2 AJP负载平衡Tomcats中删除会话ID

时间:2013-11-12 22:15:53

标签: java servlets apache2 load-balancing ajp

好的,首先我们有一个在Tomcat节点上运行的java servlet应用程序。在此之前,我们让Apache2使用ajp连接器进行负载平衡。

通常,我们会针对错误修正进行滚动更新。这需要使用Apache Jk状态管理器来禁用节点并将所有新流量重定向到活动节点。这允许用户在他们注销之前保留在旧节点上。经过漫长的等待,我通常可以停止已禁用的节点并将更新移入。然后激活该节点并禁用其他节点。

我想解决的问题是阻止非活动用户在会话结束后重新连接到已禁用的节点。文档中提到了这个问题。

  

关于将激活设置为禁用的最后注意事项:随请求发送的会话ID将作为请求URL(; jsessionid = ...)的一部分或通过cookie发送。使用长时间运行的书签或浏览器时,可以发送带有指向已禁用成员的旧的无效会话ID的请求。由于负载均衡器没有有效会话列表,因此它会将请求转发给已禁用的成员。因此排水需要比预期更长的时间。要处理此类情况,可以向Web应用程序添加Servlet过滤器,以检查请求属性JK_LB_ACTIVATION。该属性包含字符串“ACT”,“DIS”或“STP”之一。 如果检测到“DIS”并且请求的会话不再处于活动状态,请删除会话cookie并使用自引用URL重定向。重定向的请求将不再携带会话信息,因此负载均衡器不会将其发送给已禁用的工作人员。版本1.2.32中添加了请求属性JK_LB_ACTIVATION。

我的问题是参考粗体声明。如何阻止在重定向中发送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的所有内容似乎都不起作用。

2 个答案:

答案 0 :(得分:0)

How do you remove a Cookie in a Java Servlet

添加

tempCookie.setPath("/");

而不是使用完整的路径或最终离开它(似乎做)诀窍。我确信有一些深奥的解释。

答案 1 :(得分:-1)

如引言中所述。 URL中有一个; jsessionid =或请求中有一个Cookie:标题。

我不知道你为什么要进行会话搜索。您只需要测试session.isValid()。