You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在Spring Boot嵌入式Tomcat中配置Tomcat会话复制

Spring Boot嵌入式Tomcat会话复制实现指南

一、依赖配置

Spring Boot的spring-boot-starter-web默认不包含Tomcat集群相关组件,需手动引入HA依赖,注意版本要与Spring Boot内置Tomcat版本匹配(比如Spring Boot 2.7.x对应Tomcat 9.0.x,3.x对应Tomcat 10.x):

<dependency>
    <groupId>org.apache.tomcat.embed</groupId>
    <artifactId>tomcat-embed-core</artifactId>
</dependency>
<dependency>
    <groupId>org.apache.tomcat</groupId>
    <artifactId>tomcat-catalina-ha</artifactId>
    <version>${tomcat.version}</version>
</dependency>
<dependency>
    <groupId>org.apache.tomcat</groupId>
    <artifactId>tomcat-tribes</artifactId>
    <version>${tomcat.version}</version>
</dependency>

二、Java代码配置

通过自定义TomcatServletWebServerFactory配置Tomcat集群与会话复制逻辑:

import org.apache.catalina.ha.tcp.SimpleTcpCluster;
import org.apache.catalina.ha.tcp.ReplicationValve;
import org.apache.catalina.ha.session.DeltaManager;
import org.springframework.boot.web.embedded.tomcat.TomcatServletWebServerFactory;
import org.springframework.boot.web.server.WebServerFactoryCustomizer;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

@Configuration
public class TomcatClusterConfig {

    @Bean
    public WebServerFactoryCustomizer<TomcatServletWebServerFactory> tomcatClusterCustomizer() {
        return factory -> {
            factory.addContextCustomizers(context -> {
                // 初始化Tomcat集群实例
                SimpleTcpCluster cluster = new SimpleTcpCluster();
                
                // 使用DeltaManager实现会话增量复制(比全量复制效率更高)
                DeltaManager deltaManager = new DeltaManager();
                cluster.setManager(deltaManager);
                
                // 添加复制阀门,过滤需要触发会话复制的请求路径
                ReplicationValve replicationValve = new ReplicationValve();
                replicationValve.setFilter(".*\\.jsp$|.*\\.api$");
                cluster.addValve(replicationValve);
                
                // 配置集群基础属性
                cluster.setClusterName("spring-boot-tomcat-cluster");
                cluster.setChannelSendOptions(8); // 异步发送复制消息
                
                // 为当前上下文绑定集群
                context.setCluster(cluster);
            });
        };
    }
}

三、启动参数配置

添加JVM启动参数确保集群通信正常:

-Dcatalina.base=./tomcat-instance -Djava.net.preferIPv4Stack=true
  • catalina.base:指定嵌入式Tomcat的基础目录,用于存储集群临时文件
  • preferIPv4Stack=true:避免IPv6环境下的组播通信异常

四、测试验证

  1. 打包应用为可执行JAR
  2. 启动两个不同端口的实例:
    java -jar your-app.jar --server.port=8080
    java -jar your-app.jar --server.port=8081
    
  3. 在8080端口创建会话(比如登录操作),切换到8081端口验证会话是否同步

为何嵌入式Tomcat会话复制的指南如此匮乏?

  1. Spring官方主推Spring Session:Spring Boot官方更推荐Spring Session结合Redis/MongoDB等实现会话共享,这类方案跨容器、适配云原生环境,配置更简单,导致Tomcat原生方案被边缘化。
  2. Tomcat原生集群实用性低:Tomcat会话复制依赖组播或静态成员配置,云环境(如K8s)中组播通常不可用,静态成员配置繁琐,场景局限性大。
  3. 嵌入式Tomcat API门槛高:Spring Boot未对Tomcat集群功能做自动化封装,需手动操作底层API,实现成本高,社区实践自然较少。
  4. 跨容器场景限制:Tomcat原生会话复制仅适用于Tomcat集群,无法跨Jetty、Undertow等其他Servlet容器使用,不适用于微服务多容器混合部署场景。

内容的提问来源于stack exchange,提问作者Lifeweaver

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.31 22:50:46