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
Ten komentarz został usunięty przez administratora bloga.
OdpowiedzUsuń