Some time ago, I wrote my first post regarding session sharing between different web applications running on different application servers (Tomcat & Weblogic). Recently, I had to extend this architecture and include also IBM Websphere so sessions need to be shared across all three servers.
How to achieve? Pretty simple. Of course using Oracle Coherence-Web.
There's pretty easy step-by-step instruction in documentation how to set up application for Coherence 3.7 on Oracle web sites:
http://docs.oracle.com/cd/E18686_01/coh.37/e18690/cohweb.htm#CIADCHGA
Follow steps to use WebInstaller that will first inspect your EAR or WAR file and later make changes to your servlets and JSP pages. All addition steps not directly included in official Oracle docs you can find on my previous post:
http://tech-tips-adventures.blogspot.com/2013/07/oracle-coherence-web-session-sharing.html
First problem was regarding supported version of WebSphere due to official documentation says that with Coherence 3.7 only WebSphere 5.x 6.x and 7.x are supported. However I needed to set up session sharing with WebSphere 8.x.
There are 2 ways to do it. First use the latest Coherence release 12c as it officially support WS 8.
Due to I had already environment with Coherence 3.7 Tomcat & Weblogic I wanted to stick with this particular version. So I assumed that there are no big differences between 7 and 8 and it should work well in higher version. In fact it turned out it's true. Although there's no official support of WebSphere 8 in Coherence 3.7, everything is working well. So go for it!
After successfully configuring Websphere application with Coherence Web and validate that HTTSession is really kept in Coherence instead of app server heap, I went to second step to share the same session object between Tomcat, Weblogic and WebSphere.
We need to have unified JSESSIONID format on all app servers. Unfortunately, each app server has its own format for example:
Weblogic adds to JSESSIONID information about cluster members that can handle this requests after exclamation mark eg:
IVqAAz0fnTV2CxW9yrtKlbIBDou5MjT0nMrQY5UPyc8DliofKCzl!1709971477!1388404678665
WebSphere adds it too but also it adds prefix in form of 4 digits (usually 4 zeros: 0000) which points to some cache id. I'm not so familiarize with this mechanism so let's leave it alone for what reason it exists.
0000IVqAAz0fnTV2CxW9yrtKlbIBDou5MjT0nMrQY5UPyc8DliofKCzl!-1
Tomcat keeps session id in pure format without any additional prefixes or postfixes eg:
IVqAAz0fnTV2CxW9yrtKlbIBDou5MjT0nMrQY5UPyc8DliofKCzl
Coherence keeps session object with key which is equal to JSESSIONID string so if we leave it as it is than definitely session sharing will not work. Each subsequent request to different app server will generate new JSESSIONID and not maintain the old one. Basically this is because each app server expects cookie with very specific format of JSESSIONID and even it exists but format is incorrect than it generates new one every time.
So we need a mechanism to unify format of JSESSIONID somewhere in front of app servers. First idea that came to my mind was of course old good Apache. With help of mod_rewrite and mod_proxy I did simple rewriting rules to make JSESSIONID unified across different requests to different app servers. Below I pasted simple rules (don't use it on production without testing and adjusting):
rewriteEngine on
# /ibm_counter
# /tomcat_counter
# /oracle_counter
#-------------- ORACLE ----------------------
# If exists JSESSIONID with 4 zeros and request goes to ORCL then remove 4 zeros
RewriteCond $1 oracle_counter
RewriteCond %{HTTP_COOKIE} ^.*JSESSIONID=0000(.*)
RewriteRule ^(.*)$ $1 [L,R,CO=JSESSIONID:%1:%{HTTP_HOST}]
#-------------- IBM -------------------------
# If exists JSESSIONID but there is no 4 zeros and request goes to IBM the add 4 zeros
RewriteCond $1 ibm_counter
RewriteCond %{HTTP_COOKIE} ^.*JSESSIONID=(.*)$
RewriteCond %{HTTP_COOKIE} !^.*JSESSIONID=0000.*$
RewriteRule ^(.*)$ $1 [L,R,CO=JSESSIONID:0000%1:%{HTTP_HOST}]
#-------------- Tomcat ----------------------
# If exists JSESSIONID with 4 zeros and request goes to Tomcat then remove 4 zeros
RewriteCond $1 tomcat_counter
RewriteCond %{HTTP_COOKIE} ^.*JSESSIONID=0000(.*)
RewriteRule ^(.*)$ $1 [R,CO=JSESSIONID:%1:%{HTTP_HOST}]
# If exists JSESSIONID without ! at the end but request goes to TC then add !-1
# this is because TC expects ! in JSESSIONID after we set coherence-session-affinity-token in #Tomcat web.xml
RewriteCond $1 tomcat_counter
RewriteCond %{HTTP_COOKIE} ^.*JSESSIONID=(.*)
RewriteCond %{HTTP_COOKIE} !^.*JSESSIONID=.*\!.*
RewriteRule ^(.*)$ $1 [R,CO=JSESSIONID:%1\!-1:%{HTTP_HOST}]
#Oracle
ProxyPass /oracle_counter http://localhost:7004/counter/counterServlet
#IBM
ProxyPass /ibm_counter http://localhost:9080/counter/counterServlet
#Tomcat
ProxyPass /tomcat_counter http://localhost:9090/counter/counterServlet
ProxyPassMatch /img/(.*) http://localhost/counter/$1
Technology tips
piątek, 28 lutego 2014
czwartek, 11 lipca 2013
Oracle Coherence-Web: Session sharing between Weblogic and Tomcat
Recently I've been preparing a demo to show how we can share web session objects between Weblogic (12.1.1) and other application servers and in this example I've used Tomcat 6.0.37.
The task seemed to be easy as official Oracle documentation described the necessary steps well but real life experience is always different :)
If you follow the steps below you should sucessfully configure common session for WLS and Tomcat.
Assumptions:
1. I assume you have Coherence server cluster configured and running. Configuration could be done using WLS Console as in 12.1.1 it allows to manage coherence servers and clusters in the same way as normal managed servers.
2. There is simple "counter" application that stores Integer object in the session and increments the number by every http request to the app. For some reasons I used ear file in WLS and simple war file for Tomcat however the application is exactly the same. It consists simple Servlet that retrieves session and increment the counter.
3. Weblogic application is already configured with session storing in Coherence - this is simple Coherence-Web demo that I demonstrate in WINS sessions
Steps to share sessions between WLS and TC:
1. Follow official Oracle documentation how to set up your application (war) for Tomcat with Coherence:
There is webInstaller.jar that first inspect your
war file and generate coherence-web.xml with set of different
parameters that instructs your web app (war) how interact with
coherence. Later after you run webInstaller with -install option,
it changes your war file:
- by adding coherence.jar and coherence-web.jar
- by adding coherence-web.xml and by changing web.xml content
- by wrapping your servlets in com.tangosol.coherence.servlet.api23.ServletWrapper - so http request will always go through ServletWrapper first and then go to your original one.
- by adding JSP directive:
<%@ page extends="com.tangosol.coherence.servlet.api23.JspServlet" %>
- Important:
Above
directive coused that my JSPs didn't want to compile in Tomcat.
There was some problem with log() function not properly implemented
in
com.tangosol.coherence.servlet.api23.JspServlet.
So far I don't have fix for it. That was mainly the reason to test Servlets only instead of JSPs. -
You need to also remember that every time you add new servlet to your application it's worth to repeat webInstaller job with -inspect and -install options.
2. Adding tangosol-coherence-override.xml
tangosol-coherence-override.xml consists information about coherence server cluster running somewhere in the network. Tomcat container needs to connect to coherence servers and store session objects there. Without this file that correctly points to coherence server cluster, Tomcat will not join to existing cluster and initiate your own one which is not correct!tangosol-coherence-override.xml should be in war file on the classpath: for example in: WEB-INF/classes
3. Changing web.xml context parameters
You need to change some parameters in web.xml which was updated by webInstaller after -install operation.-
<param-name>coherence-session-cookie-path</param-name>
<param-value>/</param-value> -
<param-name>coherence-session-cookie-name</param-name>
<param-value>JSESSIONID</param-value> -
<param-name>coherence-scopecontroller-class</param-name>
<param-value> com.tangosol.coherence.servlet.AbstractHttpSessionCollection$GlobalScopeController </param-value> -
<param-name>coherence-session-id-length</param-name>
<param-value>52</param-value> </param-value> -
<param-name>coherence-session-affinity-token</param-name>
<param-value>!</param-value>
Parameter #2: Cookie name for both applications should be also the same. JSESSIONID is a default value but I put it here just to be sure that both apps have it identical.
Parameter #3: This parameter instructs Coherence to share objects between different applications. It must be configured on both WLS and Tomcat web.xml-s.
Parameter #4: Important! When left default, Tomcat uses 12 characters for sessin id encoding but WLS by default uses 52. When WLS gets 12 lenght session ID in cookie from Tomcat, then doesn't check if session objects exists but discard cookie without checking in coherence. This is probably just because lenght does't match. So it's very importat to make sure that cookie value lenght is the same in both apps servers.
Parameter #5: Important! WLS adds to cookie value apart of JSESSIONID also hash of managed server id. When Tomcat gets such a cookie then it needs to remove WLS hash id from cookie and then check in coherence if session already exists. Setting this parameter to ! instructs Tomcat to remove it from session.
Very important!
There is a bug in Coherence 3.7.1 causes that coherence-session-affinity-token is ignored. You need to download a patchset 6 and use coherence.jar and coherence-web.jar from 3.7.1.6. Patch for it is:
Patch 14468425: COHERENCE 3.7.1.6 FULL DISTRIBUTION
I spent 2 additional days fighting with this problem of cookie value and finally found the solution on metalink. It really shows the value of Oracle Support when developing solutions and no blog post from entire Internet doesn't mentioned about it.Take coherence.jar and coherence-web.jar from 3.7.1.6 and replace them in Tomcat application war file in WEB-INF/lib.
4. Testing your Tomcat application
Start Tomcat and using manager install your war file. Look at catalina.out if Tomcat joined the cluster mentioned in tangosol-coherence-override.xml. At this stage Tomcat should share sessions with WLS application.5. Troubleshooting
If it doesn't work like expected, check logs file from WLS managed servers and Tomcat if both servers joined the same coherence cluster.Check also cookie generated by WLS and Tomcat if it is the same with common path eg "/" and affinity suffix from WLS.
Check if your servlets get wrapped by coherence servelt on Tomcat. If not, then of course session will be taken from internal Tomcat heap instead of coherence.
You can aslo use coherence client:
java -cp $COHERENCE_HOME/lib/coherence.jar:./conf:./ com.tangosol.net.CacheFactory
where on ./conf directory you need to place tangosol-coherence-override.xml and session-cache-config.xml. You need to reffer session-cache-config.xml in tangosol-coherence-override.xml like this:
<configurable-cache-factory-config>
<init-params>
<init-param>
<param-type>java.lang.String</param-type>
<param-value system-property="tangosol.coherence.cacheconfig">
session-cache-config.xml</param-value>
</init-param>
</init-params>
</configurable-cache-factory-config>
When coherence client joins the cluster connect to appropriate cache name: session-storage. This is default cache name for storing sessions in Coherence-Web.
Issue the following command to connect to session-storage:
cache session-storage
Later you can check number of elements in cache (command: size) or try to retrieve object using command: get. The command itself will fail as this coherence client doesn't have access to appropriate java object but at least you check if object with specific key exists.
Finally, if you're still unable to make it work, contact me and I will try to help.
6. Running my "counter" examples
Here you can find ear file for WLS, and here you can find war file for Tomcat.After deploying to apps servers you can run counter servlet at the following URL:
http://<your host>:<your port>/counter/counterServlet.
Coherence cluster is called: Coherence-cluster1 and on my virtual machine can be reached at 10.0.3.15:8888.
I hope this post will be usefull for you when setting up coherence for session sharing.
Michal.
Subskrybuj:
Posty (Atom)