在 CentOS 上为 Tomcat 做负载均衡的实用方案
一、方案总览与选型
常见做法是在前端部署Nginx或Apache HTTP Server做反向代理与负载均衡,后端运行多个 Tomcat 实例。Nginx 适合高并发、七层路由与静态资源卸载;Apache 可通过 mod_jk 或 mod_proxy_ajp 与 Tomcat 的 AJP/1.3 协议通信。若需会话保持,可在 Nginx 用 ip_hash,或引入 Redis 集中式会话共享;若需高可用,可部署 Nginx 主备 + Keepalived VIP。下表对比常见方案:
| 方案 | 前端组件 | 通信协议 | 优点 | 注意点 |
|---|---|---|---|---|
| Nginx + HTTP | Nginx | HTTP/1.1 | 高并发、静态分离、七层策略丰富 | 开源版主动健康检查能力有限 |
| Apache + mod_jk | Apache | AJP/1.3 | 与 Tomcat 集成紧密、成熟稳定 | 需维护 workers.properties |
| Apache + mod_proxy_ajp | Apache | AJP/1.3 | 配置简洁、与 Apache 生态融合 | 与 mod_jk 二选一 |
以上方案均为 CentOS 上常用实践,可按并发、协议与运维偏好选择。
二、方案一 Nginx 负载均衡与高可用
http {
upstream tomcat_cluster {
least_conn;
server 192.168.1.101:8080 weight=5 max_fails=3 fail_timeout=30s;
server 192.168.1.102:8080 weight=3 max_fails=3 fail_timeout=30s;
server 192.168.1.103:8080 backup;
keepalive 32;
}
server {
listen 80;
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;
proxy_connect_timeout 5s;
proxy_read_timeout 30s;
}
# 可选:健康接口(内部使用)
location /health {
internal;
proxy_pass http://tomcat_cluster/health;
}
}
}
三、方案二 Apache HTTP Server 负载均衡
<VirtualHost *:80>
ServerName yourdomain.com
<Proxy "balancer://mycluster">
BalancerMember ajp://192.168.1.101:8009
BalancerMember ajp://192.168.1.102:8009
ProxySet lbmethod=byrequests
</Proxy>
ProxyPass / balancer://mycluster/
ProxyPassReverse / balancer://mycluster/
</VirtualHost>
worker.list=lb
worker.lb.type=lb
worker.lb.balance_workers=tomcat1,tomcat2
worker.tomcat1.type=ajp13
worker.tomcat1.host=192.168.1.101
worker.tomcat1.port=8009
worker.tomcat2.type=ajp13
worker.tomcat2.host=192.168.1.102
worker.tomcat2.port=8009
LoadModule jk_module modules/mod_jk.so
JkWorkersFile /etc/httpd/conf/workers.properties
JkLogFile /var/log/httpd/mod_jk.log
JkLogLevel info
<VirtualHost *:80>
ServerName yourdomain.com
JkMount /* lb
</VirtualHost>
<Connector port="8009" protocol="AJP/1.3" redirectPort="8443" />
四、Tomcat 集群与会话保持
<Engine name="Catalina" defaultHost="localhost" jvmRoute="tomcat1">
<Cluster className="org.apache.catalina.ha.tcp.SimpleTcpCluster">
<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" 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.TcpPingInterceptor"/>
<Interceptor className="org.apache.cajina.tribes.group.interceptors.TcpFailureDetector"/>
<Interceptor className="org.apache.catalina.tribes.group.interceptors.MessageDispatch15Interceptor"/>
</Channel>
<Valve className="org.apache.catalina.ha.tcp.ReplicationValve" filter=""/>
<ClusterListener className="org.apache.catalina.ha.session.ClusterSessionListener"/>
</Cluster>
</Engine>
五、验证与运维要点