温馨提示×

Tomcat在Linux上的集群配置

小樊
51
2026-01-03 11:19:07
栏目: 智能运维

Linux下搭建 Tomcat 集群的实用方案

一 架构与准备

  • 架构选型
    • 前端负载均衡:使用 NginxApache HTTP Server + mod_jk(AJP)
    • 会话保持:优先 Sticky Session;会话粘滞不可用时,启用 Tomcat 内置集群会话复制(DeltaManager/BackupManager)。
  • 环境与版本
    • 操作系统:CentOS 7/8Ubuntu 20.04+
    • JDK 1.8(或更高,保持各节点一致)。
    • Tomcat 8.5/9.x(保持各节点版本与配置一致)。
  • 基础准备
    • 安装 JDK 并配置环境变量(JAVA_HOME、PATH)。
    • 安装并启动 NginxApache HTTP Server
    • 规划实例端口:避免同机多实例端口冲突(HTTP、AJP、Shutdown、集群 Receiver 等)。

二 配置 Tomcat 集群节点

  • 同机双实例端口规划示例(示例值,可按需调整)
    • 实例 | HTTP | AJP | Shutdown | Receiver
      • tomcat1 | 8080 | 8009 | 8005 | 4000
      • tomcat2 | 8081 | 8010 | 8006 | 4001
  • 修改 server.xml(两个实例均配置)
    • 设置唯一 jvmRoute(与负载均衡器后端名一致):
      • tomcat1:jvmRoute=“tomcat1
      • tomcat2:jvmRoute=“tomcat2
    • 启用集群(放到 内,二选一,推荐放在 以仅对目标应用生效):
      • 最简配置:
        <Cluster className="org.apache.catalina.ha.tcp.SimpleTcpCluster"/>
        
      • 常用完整配置(UDP 组播,适合同网段):
        <Cluster className="org.apache.catalina.ha.tcp.SimpleTcpCluster"
                 channelSendOptions="8">
          <Manager className="org.apache.catalina.ha.session.DeltaManager"
                   expireSessionsOnShutdown="false"
                   notifyListenersOnReplication="true"/>
          <Channel className="org.apache.catalina.tribes.group.GroupChannel">
            <Membership className="org.apache.catalina.tribes.membership.McastService"
                        address="228.0.0.4"
                        port="45564"
                        frequency="500"
                        dropTime="3000"/>
            <Receiver className="org.apache.catalina.tribes.transport.nio.NioReceiver"
                      address="auto"
                      port="4000"   <!-- 每个实例不同:tomcat1=4000,tomcat2=4001 -->
                      autoBind="100"
                      selectorTimeout="5000"
                      maxThreads="6"/>
            <Sender className="org.apache.catalina.tribes.transport.ReplicationTransmitter">
              <Transport className="org.apache.catalina.tribes.transport.nio.PooledParallelSender"/>
            </Sender>
            <Interceptor className="org.apache.catalina.tribes.group.interceptors.TcpFailureDetector"/>
            <Interceptor className="org.apache.catalina.tribes.group.interceptors.MessageDispatch15Interceptor"/>
          </Channel>
          <Valve className="org.apache.catalina.ha.tcp.ReplicationValve" filter=""/>
          <Valve className="org.apache.catalina.ha.session.JvmRouteBinderValve"/>
          <ClusterListener className="org.apache.catalina.ha.session.JvmRouteSessionIDBinderListener"/>
          <ClusterListener className="org.apache.catalina.ha.session.ClusterSessionListener"/>
        </Cluster>
        
    • 说明
      • 组播地址 228.0.0.4:45564 需在同一二层网络;跨机房/云环境建议改用 静态成员(StaticMembershipInterceptor/TCP 单播)
      • 如仅需对某个应用启用集群,可将 放到该应用的 META-INF/context.xml 或 conf/Catalina/localhost/xxx.xml 的 中。
  • 应用开启分布式会话
    • 在应用的 WEB-INF/web.xml 中加入:
      <distributable/>
      
    • 放入会话的对象需实现 Serializable

三 配置负载均衡

  • 方案 A:Nginx(HTTP 反向代理,简单通用)
    • 配置示例(/etc/nginx/nginx.conf 或 /etc/nginx/conf.d/tomcat.conf):
      upstream tomcat_cluster {
          server 192.168.1.11:8080;
          server 192.168.1.12:8081;
          # 可选:开启最少连接或权重
          # least_conn;
          # server 192.168.1.11:8080 weight=1;
          # server 192.168.1.12:8081 weight=1;
      }
      server {
          listen 80;
          server_name your.domain;
          location / {
              proxy_pass http://tomcat_cluster;
              proxy_set_header Host $host;
              proxy_set_header X-Real-IP $remote_addr;
              proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
              proxy_set_header X-Forwarded-Proto $scheme;
          }
      }
      
    • 检查并重载:nginx -t && systemctl reload nginx
  • 方案 B:Apache HTTP Server + mod_jk(AJP,性能好)
    • 启用模块并配置 workers.properties(/etc/httpd/conf.d/mod_jk.conf 与 workers.properties):
      • httpd.conf 或 conf.modules.d/00-base.conf 中加载模块:
        LoadModule jk_module modules/mod_jk.so
        JkWorkersFile /etc/httpd/conf/workers.properties
        JkLogFile     /var/log/mod_jk.log
        JkLogLevel   info
        JkMount     /* controller
        
      • workers.properties:
        worker.list=controller,tomcat1,tomcat2
        worker.tomcat1.type=ajp13
        worker.tomcat1.host=192.168.1.11
        worker.tomcat1.port=8009
        worker.tomcat1.lbfactor=1
        
        worker.tomcat2.type=ajp13
        worker.tomcat2.host=192.168.1.12
        worker.tomcat2.port=8010
        worker.tomcat2.lbfactor=1
        
        worker.controller.type=lb
        worker.controller.balance_workers=tomcat1,tomcat2
        worker.controller.sticky_session=1
        
    • 说明
      • worker.controller.sticky_session=1 启用会话粘滞;若会话复制可靠,可设为 0 提升容错。
      • AJP 直连 Tomcat 的 8009/8010 端口,需与 server.xml 一致。

四 启动与验证

  • 启动顺序
    • 先启动所有 Tomcat 实例,确认日志无端口冲突与集群成员发现错误。
    • 启动 Nginx/Apache 负载均衡器。
  • 验证要点
    • 访问前端地址,刷新多次,观察各 Tomcat 日志是否交替命中(或按权重分布)。
    • 登录应用,获取 JSESSIONID,检查后缀是否为 .tomcat1.tomcat2(表示 jvmRoute 生效)。
    • 会话复制验证:在节点1登录后,手动停止节点1,刷新页面应仍能访问且保持登录(会话粘滞或复制生效)。
    • 防火墙/安全组:开放 80/443(Nginx/Apache)、8080/8081(Tomcat HTTP,如直连)、8009/8010(AJP)、45564/4000-4001(组播与集群通信,如启用)。

五 常见问题与优化

  • 端口与地址冲突
    • 同机多实例需确保 HTTP、AJP、Shutdown、Receiver 端口唯一;跨机部署时注意 Receiver 地址防火墙
  • 组播不通
    • 云环境/跨机房常禁用或限制 IGMP/多播,改用 静态成员 或改用 Nginx/HTTP 方案。
  • 会话粘滞与复制取舍
    • 优先 Sticky Session 减少复制流量;对写频繁会话,确保复制可靠或引入 Redis/Memcached 集中会话
  • 序列化与不可序列化对象
    • 放入 session 的对象必须 Serializable;避免存放 ClassLoader、Thread、Socket、JNI 等不可序列化对象。
  • 管理与监控
    • 使用 JConsole/VisualVM 监控堆、线程、类加载;结合 Prometheus + Grafana 采集 Tomcat/Nginx 指标并告警。

0