Pergunta

Ok, first we have a java servlet application that runs on Tomcat nodes. In front of this we have Apache2 using the ajp connector doing load-balancing.

Generally, we do rolling updates for bugfixes. This entails using the Apache Jk Status Manager to disable a node and redirect all new traffic to an active node. This allows the users to remain on the old node until they log off. After a long wait, I can generally stop the disabled node and move the update in. Then activate that node and disable the other ones.

The problem I want to solve is preventing inactive users from reconnecting to the disabled node after their session has ended. There is reference to this problem in the documentation.

A final note about setting activation to disabled: The session id coming with a request is send either as part of the request URL (;jsessionid=...) or via a cookie. When using bookmarks or browsers that are running since a long time, it is possible to send a request carrying an old and invalid session id pointing at a disabled member. Since the load balancer does not have a list of valid sessions, it will forward the request to the disabled member. Thus draining takes longer than expected. To handle such cases, you can add a Servlet filter to your web application, which checks the request attribute JK_LB_ACTIVATION. This attribute contains one of the strings "ACT", "DIS" or "STP". If you detect "DIS" and the session for the request is no longer active, delete the session cookie and redirect using a self-referential URL. The redirected request will then no longer carry session information and thus the load balancer will not send it to the disabled worker. The request attribute JK_LB_ACTIVATION has been added in version 1.2.32.

The question I have is in reference to the bolded statement. How do I prevent the sending of the JSESSION ID in the redirect.

The code I'm using right now just ends up in an infinite redirect loop.

       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;
                            }
                         }
    ...
    }

Inspecting the redirects with Firebug shows the JSESSIONID still be included in the redirect. How do I remove it? Everything I can see referring to removing cookies doesn't seem to work.

Foi útil?

Solução

How do you remove a Cookie in a Java Servlet

Adding

tempCookie.setPath("/");

rather than using the complete path or leaving it out finally did (appears to do) the trick. I'm sure there's some esoteric explanation.

Outras dicas

It's as described in the quote. There is either a ;jsessionid= in the URL or a Cookie: header in the request.

I don't know why you're doing the session search. You only need to test session.isValid().

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top