4

Update question description to be more specified and detailed.

I have a weblogic 12c, configured with one cluster, 4 node instances in the cluster, Default Load Algorithm is Round Robin, Replication Type is MAN. I deploy one web application on all 4 nodes.

What I design at first time is:

Execute logout related business logic once user session got invalidated. Put logic code inside "sessionDestroyed" method of SessionListener.java which implements HttpSession Interface. As you know, session got invalidated could be caused by 2 case, one is manually logout, another is J2ee container trigger the time out. My issue is occurred because of the 2nd case.

Issue:

The business logic code inside "SessionDestroyed" event is executed twice for one user time out, which is not expected and result in business error. What I found is Primary Http Session on the node A and Backup Session on the node B both trigger the weblogic "SessionDestroyed" event.

Question:

  1. Why Backup Session on the node B trigger session timeout event although Primary Session on the node A has already been time out ?
  2. How to let Backup Session know that Primary Session has already been invalidated?

Attach the Log, you can see the first and second line is primary session, the third line is backup session, which can be proved by the session id in the line tail.

DEBUG Oct-20-17 01:53:40 [[ACTIVE] ExecuteThread: '9' for queue: 'weblogic.kernel.Default (self-tuning)'] (AMCSessionListener-27  ) - Session: wIc4WB62vlaYR_tMRMIc0WpBHchh5fbwpinxgaig4mJRJFhlPUcj!-1795465203!1400921280!1508478820022 Created at Fri Oct 20 01:53:40 EDT 2017
DEBUG Oct-20-17 02:54:05 [[ACTIVE] ExecuteThread: '9' for queue: 'weblogic.kernel.Default (self-tuning)'] (AMCSessionListener-46  ) - Session: wIc4WB62vlaYR_tMRMIc0WpBHchh5fbwpinxgaig4mJRJFhlPUcj!-1795465203!1400921280!1508478820022 Destroyed at Fri Oct 20 02:54:05 EDT 2017
DEBUG Oct-20-17 02:55:12 [[ACTIVE] ExecuteThread: '17' for queue: 'weblogic.kernel.Default (self-tuning)'] (AMCSessionListener-46  ) - Session: wIc4WB62vlaYR_tMRMIc0WpBHchh5fbwpinxgaig4mJRJFhlPUcj!173379423!1400921280!1508478820022 Destroyed at Fri Oct 20 02:55:12 EDT 2017

Below is my weblogic configuration:

<?xml version="1.0" encoding="UTF-8"?>
<weblogic-web-app
xmlns="http://www.bea.com/ns/weblogic/90"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.bea.com/ns/weblogic/90 http://www.bea.com/ns/weblogic/90/weblogic-web-app.xsd">
  <session-descriptor>
    <cookie-path>/AppName</cookie-path>
    <persistent-store-type>replicated</persistent-store-type>
    <http-proxy-caching-of-cookies>true</http-proxy-caching-of-cookies>
    <cookie-secure>true</cookie-secure>   
  </session-descriptor>  
</weblogic-web-app>

This is my session configure in the web.xml inside web application:

<session-config>
    <session-timeout>60</session-timeout>
</session-config>

This is my SessionListener.java:

public class SessionListener implements HttpSessionListener {

    private static Logger logger = Logger.getLogger(SessionListener.class);

    @Override
    public void sessionCreated(HttpSessionEvent se) {
        if (logger.isDebugEnabled()) {
            logger.debug("Session: " + se.getSession().getId() + " Created at " + (new java.util.Date()));
        }
    }

    @Override
    public void sessionDestroyed(HttpSessionEvent se) {
        /**
         * The business logic code related to logout action
         * would be executed twice here, this is not what I want.
         **/
        if (logger.isDebugEnabled()) {
            logger.debug("Session: " + se.getSession().getId() + " Destroyed at " + (new java.util.Date()));
        }
    }
}

This code for manually logout:

@RequestMapping(value = "/logout", method = RequestMethod.GET)
public ModelAndView logout(HttpServletRequest request,
            HttpServletResponse response) throws Exception {

        ...
        // Business Logic for Logout
        ...

        request.getSession().invalidate();

        CommonViewObject vo = new CommonViewObject();
        return renderReponse(request, response, vo, "Login");
}

Any suggestion would be appreciated. I need address the issue, thank you!

Edmond Wang
  • 1,687
  • 13
  • 27

3 Answers3

1

If you force the user to logout via the invalidate()method, then HttpSessionListener sessionDestroyed() method is called twice, once when they logout, and a second time after some delayed time period.

This occurs if after the logout you redirect the user back to a web page within your application. What you're essentially doing is starting another session (which may not be immediately obvious if you haven't added security/authentication requirements to all your web pages), and the delayed second call of the sessionDestroyed() method is a timeout occurring.

The simple solution, on logout redirect the user to a web page outside of your application.

You may be interested to look :

JDev/ADF: How to log user login/logout/timeout to the database

JSP Servlet session invalidate() does not make session null

Ravi
  • 30,829
  • 42
  • 119
  • 173
  • Hi Ravi, thanks for the attention. Seems the session time out here is triggered by weblogic container itself, I have closed all web pages. – Edmond Wang Oct 26 '17 at 09:22
  • @EdmondWang Yes, it is. As I mentioned in my post. when you redirect to another page within your application by default you are having another session. – Ravi Oct 26 '17 at 17:39
0
Session: wIc4WB62vlaYR_tMRMIc0WpBHchh5fbwpinxgaig4mJRJFhlPUcj!-1795465203!1400921280!1508478820022
Session: wIc4WB62vlaYR_tMRMIc0WpBHchh5fbwpinxgaig4mJRJFhlPUcj!-1795465203!1400921280!1508478820022
Session: wIc4WB62vlaYR_tMRMIc0WpBHchh5fbwpinxgaig4mJRJFhlPUcj!**173379423**!1400921280!1508478820022

Third log line indicates the session being created in different primary jvm / node ( 173379423 ) compare two first two (-795465203).

this may not relate to the session.invalidate calls rather it has problem of creating two session (two different primary node) and expired after time out

I could think of two possible use case

  1. LB is having issues with stickiness. it might got fwd-ed the request to another node which got expired after 60 mins
  2. Primary jvm (node a) may went bad and recover its own , during the window cluster replicated the primary session to new node (node c) , However LB might not noticed the (node a) due to health monitor interval and continued with original primary jvm ( node a)

UPDATE:

  1. Why backup session not trigger session created event? 2. Ideally, is that backup session should timeout with primary session transparently?
  There is no second session being created!!.

Let me try to explain the flow.

  • LB ( F5) receives first request from client.
  • LB routes the traffic to the Node as Round Robin Basis . Picked Node A
  • Node A Generates the session and marked as primary creates Secondary Backup based on its cluster Ranking ( Assume Node B) and pass sessionid as part of Cookies for further communication.

  • Further Requests to LB , LB would check the Cookies and based on Server identifier its routes the traffic to the Node A

  • Node A went Bad / connection issues between Lb to Node A , Now LB cannot route based on Cookie's information , so LB can pick any node based on Round Robin and sends the request to an new Node ( Node D) . At this point Node D pulls session from Secondary based on Cookie information being passed as part request and marked as primary and Node B would remain secondary.

    • Note** , if we have used HttpClusterServlet proxy ( for example apache proxy) and used and (Weblogic Plugin (HttpClusterServlet)) to do load balancing in front your weblogic , then HttpClusterServlet should able to collect your secondary server information ( host and port) and route the traffic to secondary back server. Now Node B would become primary and new secondary would picked based on Node B's cluster ranking.

All session replications should be transparent to the client and there is no second session created in above case.

Note** , in both the cases (LB / Proxy based routing ) the session created in Node A considered as Orphaned , since the session got new primary and secondary . So when users session get invalidate it would invalidate in both current primary and secondary Nodes.

Weblogic documentation provides additional information abt this use case.

Would suggest to track the session based on access log / applications logs to verify when the calls moved to next node. Also make sure LB health monitor request in access logs during the same time period

Would also suggest to make sure the LB configured with Cookie persistent profile.

Mani
  • 3,274
  • 2
  • 17
  • 27
  • I think the case 2 got more possible. However, I have to change session persistent store type from 'replicated' to 'memory' for now, as this issue has been there for more than one month, I cannot bring it into another release cycle. Do you know is there a way to debug this, so that I can continue track this issue? – Edmond Wang Nov 08 '17 at 01:45
  • @Main, 2 more questions hoping your reply:1. Why backup session not trigger session created event? 2. Ideally, is that backup session should timeout with primary session transparently? – Edmond Wang Nov 08 '17 at 02:00
0

I guess you are using the default spring security configuration which by default enables CSRF check, so you may need to disable it and check again

http.csrf().disable()
Hany Sakr
  • 2,591
  • 28
  • 27