3
votes

We are implementing a small farm (2 nodes) of Tomcat installed across two slices in Azure, and putting the Azure load balancer in front. This is basically a round-robin, non-sticky-session balancer.

The webapp uses Tomcat's container managed security (forms authentication, currently via DataSourceRealm.

As the user gets round-robin'ed to the node they are not authenticated against, as we expected, they get authentication errors.

I've done a fair amount of research, and there doesn't seem to be a single prescribed way for dealing with this... It has been suggested that we put the nodes behind an Apache server and use mod_jk; that we redesign the authentication process to use a cookie to confirm authentication; that we use Tomcat clustering.

What would be the simplest way for us to achieve this? Our app does not use sessions for anything (other than Tomcat's CMS). We'd rather not go off of Tomcat's CMS, though we aren't averse to building out a JAAS implementation if necessary. But really, the only thing we need to support is cross-node authentication.

Any help appreciated!

EDIT: We attempted memcached on Azure, got the following:

2013-07-08 21:50:55.463 INFO net.spy.memcached.MemcachedConnection:  Connection state changed for sun.nio.ch.SelectionKeyImpl@dcd4755
2013-07-08 21:50:55.463 INFO net.spy.memcached.MemcachedConnection:  Reconnecting due to failure to connect to {QA sa=srvr.cloud.com/1XX.1XX.1XX.1XX:11XXX, #Rops=0, #Wops=0, #iq=0, topRop=null, topWop=null, toWrite=0, interested=0}
java.net.ConnectException: Connection timed out: no further information
                at sun.nio.ch.SocketChannelImpl.checkConnect(Native Method)
                at sun.nio.ch.SocketChannelImpl.finishConnect(Unknown Source)
                at net.spy.memcached.MemcachedConnection.handleIO(MemcachedConnection.java:399)
                at net.spy.memcached.MemcachedConnection.handleIO(MemcachedConnection.java:247)
                at net.spy.memcached.MemcachedConnection.run(MemcachedConnection.java:915)

Our context.xml:

<Manager className="de.javakaffee.web.msm.MemcachedBackupSessionManager"
    memcachedNodes="n1:srvr.cloud.com:11XXX"
    sticky="false"
    sessionBackupAsync="false"
    lockingMode="uriPattern:/path1|/path2"
    requestUriIgnorePattern=".*\.(ico|png|gif|jpg|css|js)$"
    transcoderFactoryClass="de.javakaffee.web.msm.JavaSerializationTranscoderFactory"
    />
1

1 Answers

3
votes

An approach would be to host memcached on the servers, or Windows Azure Caching, and leverage memcached-session-manager to share session data between the Tomcat servers.

"memcached-session-manager is a tomcat session manager that keeps sessions in memcached, for highly available, scalable and fault tolerant web applications. It supports both sticky and non-sticky configurations, and is currently working with tomcat 6.x and 7.x. For sticky sessions session failover (tomcat crash) is supported, for non-sticky sessions this is the default (a session is served by default by different tomcats for different requests). Also memcashed failover (memcached crash) is supported via migration of sessions. There shall also be no single point of failure, so when a memcached fails the session will not be lost (but either be available in tomcat or in another memcached)."

See a slightly outdated discussion at this answer.