Showing posts with label sessionaffinity. Show all posts
Showing posts with label sessionaffinity. Show all posts

Effect on JSESSIONID in case of Server failure

Server clusters provide a solution for failure of an application server. Sessions created by cluster members in the server cluster share a common persistent session store. Therefore, any cluster member in the server cluster has the ability to see any user’s session saved to persistent storage. If one of the cluster members fail, the user can continue to use session information from another cluster member in the server cluster. This is known as failover. Failover works regardless of whether the nodes reside on the same machine or several machines.

After a failure, WebSphere redirects the user to another cluster member, and the user’s session affinity switches to this replacement cluster member. After the initial read from the persistent store, the replacement cluster member places the user’s session object in the in-memory cache, assuming the cache has space available for additional entries.

The Web server plug-in maintains the cluster member list in order and picks the cluster member next in its list to avoid the breaking of session affinity. From then on, requests for that session go to the selected cluster member. The requests for the session go back to the failed cluster member when the failed cluster member restarts.

I tried this with my SessionAffinity.war, after establishing session with Server 2 i stopped that server and then i tried sending request to web server. The JSESSIONID was changed after 1 request and now the clone Id part was pointing to server 4

How to find out the WAS server handling request from JSESSIONID

Debugging problems in distributed environment is little more difficult then debugging problems in the Standalone environment, because how do you find out the server that is handling the request. The JSESSIONID cookie value contains the identifier of the server that is handling the request, take a look at Session Affinity for more details.

I wanted to try this so i created a simple SessionAffinityServlet like this

public class SessionAffinityServlet extends HttpServlet {
private static final long serialVersionUID = 1L;
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
response.setContentType("text/html");
System.out.println("Inside SessionAffinity.doGet()");
HttpSession httpSession = request.getSession();
response.getWriter().println("Session Name " + ServerName.getFullName() +"
");
response.getWriter().println("Session Id " + httpSession.getId() +"
");
Cookie[] cookies = request.getCookies();
for( int i = 0 ; i < cookies.length ;i++){
response.getWriter().println(cookies[i].getName() + " " + cookies[i].getValue() +"
");
}

}
}


As you can see only thing that i am doing in the doGet() method is reading the value of all the cookies and writing them to output. I am also writing out name of the server handling the request in the output.

I deployed this code to server and when i tried hitting the server and i see values like this.




Now if i take the value of JSESSIONID the last part of the value is 14dtuu8g3. Now take this value and open the plugin-cfg.xml for web server plugin and search this value in it. You will find a Server element with value of CloneID matching the value from JSESSIONID that is the server dmgrNode01_server2 , handling the user request

<ServerCluster CloneSeparatorChange="false" GetDWLMTable="false" IgnoreAffinityRequests="true" LoadBalance="Round Robin" Name="cluster1" PostBufferSize="64" PostSizeLimit="-1" RemoveSpecialHeaders="true" RetryInterval="60">
<Server CloneID="14dtuu8g3" ConnectTimeout="0" ExtendedHandshake="false" LoadBalanceWeight="2" MaxConnections="-1" Name="dmgrNode01_server2" ServerIOTimeout="0" WaitForContinue="false">
<Transport Hostname="dmgr.webspherenotes.com" Port="9081" Protocol="http"/>
<Transport Hostname="dmgr.webspherenotes.com" Port="9444" Protocol="https">
<Property Name="keyring" Value="C:\Cert\HTTPServer\Plugins/config/webserver1/plugin-key.kdb"/>
<Property Name="stashfile" Value="C:\Cert\HTTPServer\Plugins/config/webserver1/plugin-key.sth"/>
</Transport>
</Server>
<Server CloneID="14dtuueci" ConnectTimeout="0" ExtendedHandshake="false" LoadBalanceWeight="2" MaxConnections="-1" Name="dmgrNode01_server4" ServerIOTimeout="0" WaitForContinue="false">
<Transport Hostname="dmgr.webspherenotes.com" Port="9082" Protocol="http"/>
<Transport Hostname="dmgr.webspherenotes.com" Port="9445" Protocol="https">
<Property Name="keyring" Value="C:\Cert\HTTPServer\Plugins/config/webserver1/plugin-key.kdb"/>
<Property Name="stashfile" Value="C:\Cert\HTTPServer\Plugins/config/webserver1/plugin-key.sth"/>
</Transport>
</Server>
<PrimaryServers>
<Server Name="dmgrNode01_server2"/>
<Server Name="dmgrNode01_server4"/>
</PrimaryServers>
</ServerCluster>


As you can see the plugin-cfg.xml has a ServerCluster element that has two Server child elements, that means the cluster has two servers and plugin will forward request to either of them

You can download the sample code from here