Search code examples
spring-boottomcatsession-replication

How to setup Tomcat Session Replication with Spring Boot embedded tomcat


I haven't been able to find any guide on how to programmatically setup tomcat session replication when using an embedded tomcat with spring boot. It was even a hard time finding out about the "tomcat-catalina-ha" dependency.

I have a working Tomcat session replication example working when setup on a non-embedded tomcat, but converting it over to Java config hasn't been working. I looked into Hazelcast, but a few of the options I need require the enterprise license. I've also been told that storing sessions in a traditional database doesn't scale well.

I'm looking for a guide or example project that implements Tomcat session replication using an embedded tomcat. Barring that, I'd be interested in why there are no guides in the first place?


Solution

  • So after more research, I found this documentation:

    The list listed here is the only place that configuration and how-to questions belong, ever.

    Looking through the mailing list archive, I was able to find one example of programmatic cluster configuration: https://marc.info/?l=tomcat-user&m=160220406421937&w=2

    It was able to take me most of the way, I had been setting my cluster on the context via:

    @Configuration
    public class MyConfig implements WebServerFactoryCustomize<TomcatServletWebServerFactory> {
    
    @Override
    public void customize(TomcatServletWebServerFactory factory) {
        factory.addContextCustomizers(context -> {
            //cluster setup
            SimpleTcpCluster simpleTcpCluster = new SimpleTcpCluster();
            // order of your interceptors does matter fyi
            // rest of setup details, very similar to mailing list archive
    
            // Make sure the DeltaManager is created for me
            context.setDistributable(true);
    
            // The key point:
            //context.setCluster(simpleTcpCluster);
    
            // The fix instead of context.setCluster
            // context.getParent() is an instance of StandardHost
            // And if you are coping from a server.xml, it's also clear
            // that the cluster element is set on the host
            context.getParent().setCluster(simpleTcpCluster);
    
            // Basically by setting it on the `host`, it allows the startup to 
            // recognize it early enough to start the cluster up.
        });
    }
    

    When I set the cluster on the context, none of the cluster elements were ever actually started.

    I would also note that when investigating this, I found an article(2013) showing how to load a server.xml when using an embedded tomcat, although I didn't not try it.

    Final note: I used the StaticMembershipService vs the multicast stuff, or the StaticMembershipInterceptor.