nginx转发至多个tomcat即实现负载均衡,因其upstream模块原生支持轮询等策略,无需中间件或改java代码;只需各tomcat监听不同http端口并部署相同应用,配合proxy_pass即可分发请求。

为什么直接用 nginx 转发到多个 tomcat 实例就能算负载均衡
因为 nginx 的 upstream 模块原生支持轮询(默认)、加权轮询、IP哈希等策略,只要把多个 tomcat 的 http 端口(如 8080、8081)注册进 upstream,它就会自动分发请求。不需要额外中间件或 Java 代码参与调度逻辑。
关键点在于:Java 应用本身不用改任何代码,tomcat 只需独立启动、监听不同端口,状态保持(如 session)需额外处理,否则用户刷新可能跳到另一个实例导致登录失效。
-
tomcat实例必须部署完全相同的 Web 应用(.war或解压目录一致) - 每个
tomcat的server.xml中Connector端口不能冲突,例如:port="8080"、port="8081" -
nginx不代理 AJP(除非你显式配ajp://),只走 HTTP,所以tomcat的 HTTP connector 必须启用且可访问
如何配置 nginx 的 upstream 实现轮询与故障剔除
在 nginx.conf 的 http 块里定义 upstream,并用 proxy_pass 引用它。最简可用配置如下:
upstream backend_tomcats {
server 127.0.0.1:8080 max_fails=3 fail_timeout=30s;
server 127.0.0.1:8081 max_fails=3 fail_timeout=30s;
}
server {
listen 80;
location / {
proxy_pass http://backend_tomcats;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
}
}
说明:
立即学习“Java免费学习笔记(深入)”;
-
max_fails=3表示连续 3 次健康检查失败后标记该tomcat为不可用 -
fail_timeout=30s表示 30 秒内不向该节点转发请求;超时后会尝试恢复探测 - 默认是轮询,无需写
least_conn或ip_hash,除非你有特定需求 - 务必保留
proxy_set_header,否则 Java 应用中request.getRemoteAddr()拿到的是127.0.0.1,不是真实客户端 IP
tomcat 集群下 session 共享的三种现实选择
不处理 session,用户就可能反复登录。Java 层面没有银弹,得按实际约束选:
- 用
nginx的ip_hash:简单但不推荐——NAT 环境下所有用户被当成同一个 IP;扩容缩容时 hash 重分布,老 session 失效 - 配置
tomcat的Cluster(如 DeltaManager):依赖组播或静态成员列表,网络环境受限(云主机常禁组播),且同步延迟高,小集群勉强可用 - 外置 session 存储(推荐):把 session 写入
redis或memcached,用tomcat-redis-session-manager这类插件。注意 Redis 要开启持久化或主从,否则单点挂掉全集群登出
如果应用本身无状态(比如 JWT 认证),那就根本不用共享 session——这是最干净的解法,但需要前端和认证逻辑配合改造。
验证是否真走了负载均衡:别只看日志,要看 nginx 的 stub_status 和 tomcat 的访问日志时间戳
光看浏览器刷新没用。正确验证方式:
- 打开
nginx的stub_status模块(编译时默认包含),加一段location /nginx_status,用curl查实时连接数和请求计数 - 在两个
tomcat的conf/logging.properties中调高org.apache.catalina.core.ContainerBase.[Catalina].[localhost].level = FINE,观察localhost_access_log时间戳是否交替出现 - 用
ab或wrk发起并发请求(如wrk -t4 -c100 -d10s http://localhost/),再对比两台tomcat日志里的请求数是否接近(轮询下应大致均分)
容易忽略的是:本地测试时若两个 tomcat 都跑在本机,而 nginx 也跑本机,CPU/IO 瓶颈可能掩盖负载差异;生产环境务必跨机器部署,且监控各节点的 CPU、heap、thread count。










