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



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

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

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

关于将激活设置为禁用的最后一个注意事项:请求附带的会话 ID 作为请求 URL 的一部分发送 (;jsessionid=...) 或通过 cookie 发送。使用长时间运行的书签或浏览器时,可以发送带有指向已禁用成员的旧且无效的会话 ID 的请求。由于负载均衡器没有有效会话的列表,因此它会将请求转发给禁用的成员。因此,排水时间比预期的要长。要处理此类情况,您可以向 Web 应用程序添加一个 Servlet 过滤器,该过滤器检查请求属性JK_LB_ACTIVATION。此属性包含字符串"ACT"、"DIS"或"STP"之一。如果您检测到"DIS"并且请求的会话不再处于活动状态,请删除会话 Cookie 并使用自引用 URL 重定向。然后,重定向的请求将不再携带会话信息,因此负载均衡器不会将其发送给已禁用的工作线程。请求属性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 仍包含在重定向中。如何删除它?我能看到的关于删除饼干的所有内容似乎都不起作用。

如何在 Java Servlet 中删除 Cookie

添加

tempCookie.setPath("/");

而不是使用完整的路径或将其排除在外,最终(似乎确实)了这个技巧。我敢肯定有一些深奥的解释。

正如引用中所述。URL 中有一个 ;jsessionid=,或者请求中有一个 Cookie: 标头。

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

最新更新