整体架构与思路
生产环境中通常由反向代理/负载均衡器(如 Nginx、Apache HTTP Server)在前面分发请求,后端运行多个 Tomcat 实例。为提升可用性与伸缩性,可结合 会话保持(Sticky)或 Tomcat 集群会话复制(DeltaManager/BackupManager)来保证用户会话不丢失。动静分离也常一并实施:静态资源由负载均衡器或 CDN 处理,动态请求转发到 Tomcat。
方案一 Nginx 反向代理与负载均衡
- 基本 HTTP 负载均衡
- 在 upstream 中声明多个 Tomcat 节点,使用 proxy_pass 转发请求,并设置必要的请求头以透传客户端信息。
- 示例要点:
- upstream 定义后端列表(如 192.168.1.101:8080、192.168.1.102:8080)
- server 监听 80 端口,location / 代理到 upstream
- 设置 Host、X-Real-IP、X-Forwarded-For、X-Forwarded-Proto 等头
- 会话保持
- 使用 ip_hash 实现基于客户端 IP 的粘性会话,同一用户请求尽量落到同一实例。
- 健康检查与权重
- 通过 nginx_upstream_check_module 增加主动健康检查(需编译进 Nginx)
- 使用 weight 设置权重、backup 标记备用节点
- 动静分离
- 对 jpg|jpeg|gif|css|js|png|html|txt 等静态资源直接由 Nginx 本地或 CDN 提供,动态请求再反向代理到 Tomcat。
方案二 Apache HTTP Server 负载均衡
- 启用模块
- 启用 mod_proxy、mod_proxy_http(或 mod_proxy_ajp),必要时启用 mod_proxy_balancer。
- 基于 HTTP 的负载均衡
- 使用 ProxyPass / balancer://mycluster/ 与 ProxyPassReverse,在 <Proxy balancer://mycluster> 中声明多个 BalancerMember(如 http://tomcat1:8080、http://tomcat2:8080)。
- 会话保持
- 使用 stickysession=JSESSIONID 实现粘性会话;为各节点设置 route=node1、route=node2 便于路由绑定。
- 基于 AJP 的负载均衡(可选)
- 使用 mod_proxy_ajp 或 mod_jk 通过 AJP 8009 端口连接 Tomcat,配置 workers.properties 定义后端列表与负载策略。
Tomcat 集群与会话复制
- 在 server.xml 中启用 SimpleTcpCluster,配置 Channel(Membership、Receiver、Sender、Interceptor)、ReplicationValve、JvmRouteBinderValve 与 ClusterListener,用于节点间会话复制与故障检测。
- 在应用的 context.xml 或 META-INF/context.xml 中配置可分布式会话的 Manager(如 DeltaManager),并在 web.xml 添加 标记,使会话数据在集群内复制。
- 会话保持策略选择
- 粘性会话:配置简单、延迟低,但存在单点风险。
- 会话复制:高可用、无状态扩展,需网络与序列化开销,注意复制粒度与性能调优。
验证与运维要点
- 验证负载分发
- 多次请求观察是否分发到不同 Tomcat;使用 curl -I 查看响应头或自定义日志区分实例。
- 健康检查与日志
- 关注 Nginx 的 access.log/error.log 或 Apache 的 access_log/error_log;结合主动健康检查与被动失败探测提升稳定性。
- 监控与压测
- 通过 /manager/status?XML=true 查看实例状态;使用 ab 等工具进行压测(如 ab -n 10000 -c 500)。
- 性能与安全
- 在 server.xml 配置 Executor 线程池;优化 JVM 参数(如 -Xms/-Xmx、G1GC);启用 gzip 压缩;对外仅暴露负载均衡器,后端 Tomcat 置于内网。