Ubuntu Tomcat如何集群配置
小樊
42
2025-12-26 19:29:36
Ubuntu Tomcat 集群配置实操指南
一 架构与准备
- 架构建议:前端使用 Nginx/Apache HTTPD 做负载均衡,后端部署 2 个及以上 Tomcat 实例 组成集群,开启会话复制(如 DeltaManager),实现高可用与横向扩展。
- 环境与版本:操作系统建议 Ubuntu 20.04+;JDK 8/11;Tomcat 9/10(各节点版本保持一致)。
- 基础准备:安装 JDK 并配置环境变量(如 JAVA_HOME),下载解压 Tomcat 到不同目录(如 /opt/tomcat1、/opt/tomcat2),保证各实例端口不冲突。
- 主机名解析与网络:在 /etc/hosts 为各节点配置主机名与内网 IP,确保 InetAddress.getLocalHost().getHostAddress() 返回非 127.0.0.1 的地址,避免集群通信异常。
- 时间同步:所有节点启用 NTP 时间同步,避免因时间漂移导致会话过期判断异常或集群不稳定。
- 防火墙放行:开放 HTTP 80/443(或 8080)、AJP 8009(如使用 AJP)、以及集群通信端口(见下文的 Receiver 端口 与 组播 45564/UDP)。
二 安装与端口规划
- 安装 Tomcat(示例以 Tomcat 9 为例,两台节点分别解压到不同目录):
- 下载与解压:
- wget https://dlcdn.apache.org/tomcat/tomcat-9/v9.0.87/bin/apache-tomcat-9.0.87.tar.gz
- sudo tar -zxvf apache-tomcat-9.0.87.tar.gz -C /opt
- sudo mv /opt/apache-tomcat-9.0.87 /opt/tomcat-cluster-node1
- 在另一台节点重复,目录改为 /opt/tomcat-cluster-node2
- 环境变量(可选,便于多实例管理):
- echo ‘export CATALINA_HOME=“/opt/tomcat-cluster-node1”’ >> /etc/profile
- echo ‘export PATH=$PATH:$CATALINA_HOME/bin’ >> /etc/profile
- source /etc/profile
- 端口规划(示例两台机器的实例端口规划如下,可按需调整):
| 节点 |
Server port |
HTTP |
AJP |
Receiver port |
| node1 |
8005 |
8080 |
8009 |
4000 |
| node2 |
8006 |
8081 |
8010 |
4001 |
- 在同一台机器运行多个实例时,必须确保 Server port、HTTP、AJP、Receiver port 均不冲突;必要时为各实例设置不同的 jvmRoute(配合 AJP 粘性会话)。
三 配置 Tomcat 集群与会话复制
- 方式 A 快速默认集群(适合节点数较少,如少于 10 台):
- 在 $CATALINA_HOME/conf/server.xml 的 中取消注释或新增:
- 将需要会话复制的应用在其 WEB-INF/web.xml 中加入:
- 确保放入 Session 的对象实现 java.io.Serializable。以上即可完成最简集群与会话复制。
- 方式 B 显式配置(可控性与可观测性更好):
- 在 内添加如下 Cluster 配置,按需调整端口与网卡:
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- 关键说明:
- Membership 使用组播 228.0.0.4:45564/UDP 发现成员;跨机房或云环境若无组播,可改用 StaticMembershipInterceptor 静态配置成员。
- Receiver port=“4000” 为接收复制消息端口,同一物理机多实例需改为不同端口。
- Manager 可用 DeltaManager(全量复制,适合小集群)或 BackupManager(备份复制,适合较大集群)。
- 将需要会话复制的应用加入 ,并确保会话属性对象可序列化。
四 配置负载均衡
- 方案 1 Apache HTTP Server + mod_jk(AJP):
- 安装模块:sudo apt-get install libapache2-mod-jk
- 配置 workers.properties(示例为两台节点):
- worker.list=loadbalancer,status
- worker.tomcat1.port=8009
- worker.tomcat1.host=192.168.0.11
- worker.tomcat1.type=ajp13
- worker.tomcat1.lbfactor=1
- worker.tomcat2.port=8009
- worker.tomcat2.host=192.168.0.12
- worker.tomcat2.type=ajp13
- worker.tomcat2.lbfactor=1
- worker.loadbalancer.type=lb
- worker.loadbalancer.balance_workers=tomcat1,tomcat2
- worker.loadbalancer.sticky_session=1
- worker.status.type=status
- 启用模块并配置 mod_jk:
- a2enmod jk
- 在 /etc/apache2/mods-enabled/jk.conf 或 apache2.conf 中:
- LoadModule jk_module modules/mod_jk.so
- JkWorkersFile /path/to/workers.properties
- JkLogFile /var/log/apache2/mod_jk.log
- JkLogLevel info
- <VirtualHost *:80>
- ServerName yourdomain.com
- JkMount /* loadbalancer
- JkMount /jk-status status
-
- 重启 Apache:sudo systemctl restart apache2。
- 方案 2 Nginx 或 HAProxy(HTTP):
- Nginx 示例(HTTP 轮询):
- upstream backend {
- server 192.168.0.11:8080;
- server 192.168.0.12:8080;
-
如需会话保持(粘性会话),可添加:ip_hash;
- }
- server {
- listen 80;
- location / {
- proxy_pass http://backend;
- }
- }
- HAProxy 示例(HTTP 轮询):
- frontend http-in
- bind *:80
- default_backend servers
- backend servers
- balance roundrobin
- server s1 192.168.0.11:8080 check
- server s2 192.168.0.12:8080 check
- 提示:使用 HTTP 代理时,Tomcat 侧通常无需开启 AJP;使用 AJP 时选择 mod_jk 更常见。
五 部署与验证
- 部署应用:将应用(已加入 )部署到各节点的 webapps,或统一共享目录;确保应用会话对象可序列化。
- 启动顺序:先启动所有 Tomcat 实例,再启动 Apache/Nginx/HAProxy。
- 验证要点:
- 访问应用,观察日志是否出现 JOINED/MESSAGE 等集群事件;使用 PSI Probe 等工具查看节点与会话状态。
- 会话粘性与复制:
- 使用 mod_jk + sticky_session=1 时,刷新页面 JSESSIONID 后缀通常不变;关闭当前节点后,若会话仍可用,说明会话复制生效(或会话保持生效)。
- 关闭 sticky_session 或节点宕机后仍能保持登录,说明会话复制在集群内生效。
- 组播连通性(如采用组播发现):在节点上抓包或利用工具测试 228.0.0.4:45564/UDP 的收发,确保网络与防火墙策略允许。
- 常见问题与优化:
- 节点无法互相发现:检查 组播地址/端口 一致、网络与防火墙放行 45564/UDP;云环境若无组播,改用 StaticMembershipInterceptor 静态成员配置。确认 Receiver address 为本机非 127.0.0.1 的 IP,且多实例 Receiver port 不冲突。
- 会话不复制或丢失:应用 web.xml 缺少 、会话对象未实现 Serializable、或 ReplicationValve 未生效。
- 时间不同步导致会话过期判断异常,启用 NTP 同步时间。
- 单台机器运行多实例:必须修改 SHUTDOWN、HTTP、AJP、Receiver 端口,避免端口冲突;必要时为各实例设置不同的 jvmRoute(配合 AJP 粘性会话)。
- 高可用增强:在 Apache/Nginx/HAProxy 前增加 Keepalived 实现 VRRP 虚拟 IP,避免单点故障。