Web 架構中,Apache/Nginx 作為反向代理層分發流量至後端 Tomcat 集群是經典模式。本文提供 Apache mod_proxy_balancer 與 Nginx upstream 兩套完整配置,對比單文件與多文件模塊化配置優劣,含健康檢查、會話保持、靜態資源分離、啟動腳本等生產級細節。
# 源碼編譯
./configure --prefix=/usr/local/apache --enable-proxy --enable-proxy-balancer --enable-proxy-http
make && make install
# YUM 安裝
yum install httpd mod_ssl
# 確認模塊載入
httpd -M | grep proxy
# /etc/httpd/conf.d/tomcat_balancer.conf
Listen 8051
ServerAdmin admin@example.com
ServerName lb.example.com
ErrorLog "/var/log/httpd/tomcat_balancer_error.log"
CustomLog "/var/log/httpd/tomcat_balancer_access.log" common
# 負載均衡核心配置
ProxyPass / balancer://tomcat_cluster/ stickysession=JSESSIONID|jsessionid nofailover=On lbmethod=byrequests timeout=5 maxattempts=3
ProxyPassReverse / balancer://tomcat_cluster/
ProxyRequests Off
ProxyPreserveHost On
# BalancerMember ajp://192.168.1.10:8009 route=tomcat_a
BalancerMember https://192.168.1.10:8080/App route=tomcat_a
# BalancerMember ajp://192.168.1.11:8010 route=tomcat_b
BalancerMember https://192.168.1.11:8081/App route=tomcat_b
關鍵參數:
stickysession=JSESSIONID|jsessionid:會話保持,支持 Cookie 和 URL 重寫nofailover=On:會話節點掛掉返回 503,不重定向到其他節點(避免會話丟失)lbmethod=byrequests:請求計數分發(默認),可選 bytraffic/bybusynessroute=tomcat_a:對應 Tomcat server.xml jvmRoute="tomcat_a"
...
groupadd nginx && useradd -g nginx -s /sbin/nologin nginx
yum install -y make zlib-devel openssl-devel pcre-devel
tar zxvf nginx-1.18.0.tar.gz && cd nginx-1.18.0
./configure --prefix=/usr/local/nginx \
--with-http_ssl_module --with-http_gzip_static_module --with-http_stub_status_module \
--with-http_realip_module --with-stream
make && make install
# /usr/local/nginx/conf/nginx.conf
user nginx;
worker_processes auto;
error_log logs/error.log warn;
pid logs/nginx.pid;
events {
use epoll;
worker_connections 65535;
multi_accept on;
}
http {
include mime.types;
default_type application/octet-stream;
# 性能優化
sendfile on;
tcp_nopush on;
tcp_nodelay on;
keepalive_timeout 65;
client_max_body_size 100m;
# Gzip
gzip on;
gzip_min_length 1k;
gzip_comp_level 2;
gzip_types text/plain application/javascript text/css application/xml;
# 上游定義
upstream app_cluster {
server 192.168.1.10:8080 weight=1 max_fails=2 fail_timeout=30s;
server 192.168.1.11:8081 weight=1 max_fails=2 fail_timeout=30s;
# keepalive 32; # 長連接池
}
upstream admin_cluster {
server 192.168.1.10:8080 weight=1 max_fails=2 fail_timeout=30s;
server 192.168.1.11:8081 weight=1 max_fails=2 fail_timeout=30s;
}
server {
listen 80;
server_name localhost;
location /App {
proxy_pass https://app_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_next_upstream error timeout http_500 http_502 http_503 http_504;
proxy_connect_timeout 5s;
proxy_read_timeout 60s;
}
location /Admin {
proxy_pass https://admin_cluster;
# 同樣 proxy_set_header...
}
}
}
# 目錄結構
/usr/local/nginx/conf/
├── nginx.conf # 主配置
├── conf.d/
│ ├── gzip.conf # 壓縮配置
│ ├── proxy.conf # 代理通用參數
│ ├── upstream.conf # 上游定義
│ └── vhosts/
│ ├── app.conf # 業務虛擬主機
│ └── admin.conf # 管理虛擬主機
nginx.conf:
user nginx;
worker_processes auto;
include conf.d/proxy.conf;
include conf.d/gzip.conf;
include conf.d/upstream.conf;
include conf.d/vhosts/*.conf;
conf.d/upstream.conf:
upstream app_cluster {
server 192.168.1.10:8080 max_fails=1 fail_timeout=60s;
server 192.168.1.11:8081 max_fails=1 fail_timeout=60s;
keepalive 64;
}
upstream admin_cluster {
server 192.168.1.10:8080 max_fails=1 fail_timeout=60s;
server 192.168.1.11:8081 max_fails=1 fail_timeout=60s;
}
conf.d/proxy.conf:
proxy_connect_timeout 5s;
proxy_read_timeout 60s;
proxy_send_timeout 10s;
proxy_buffer_size 64k;
proxy_buffers 8 64k;
proxy_busy_buffers_size 128k;
proxy_temp_file_write_size 256k;
proxy_next_upstream error timeout http_500 http_502 http_503 http_504;
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_http_version 1.1;
proxy_set_header Connection "";
conf.d/vhosts/app.conf:
server {
listen 80;
server_name app.example.com;
location / {
proxy_pass https://app_cluster;
}
# 靜態資源直接由 Nginx 服務
location ~* \.(jpg|jpeg|png|gif|ico|css|js|woff|woff2)$ {
root /data/www/app;
expires 30d;
add_header Cache-Control "public";
}
}
# /etc/init.d/nginx
#!/bin/bash
# chkconfig: 345 99 20
PROG="/usr/local/nginx/sbin/nginx"
PIDF="/usr/local/nginx/logs/nginx.pid"
case "$1" in
start) $PROG; echo "Nginx started." ;;
stop) kill -s QUIT $(cat $PIDF); echo "Nginx stopped." ;;
restart) $0 stop; $0 start ;;
reload) kill -s HUP $(cat $PIDF); echo "Nginx reloaded." ;;
*) echo "Usage: $0 {start|stop|restart|reload}"; exit 1 ;;
esac
chmod +x /etc/init.d/nginx
chkconfig --add nginx
chkconfig --level 2345 nginx on
test.jsp 輸出節點標識https://lb.example.com:8051/App/test.jsp (Apache) 或 https://app.example.com/App/test.jsp (Nginx)tomcat_a / tomcat_b 間切換 → 負載均衡生效nofailover=On 會報 503,Nginx 默認切換)| 維度 | Apache (mod_proxy) | Nginx |
|---|---|---|
| 並發模型 | 多進程/線程(Prefork/Worker/Event) | 事件驅動單進程多線程 |
| 靜態文件性能 | 一般 | 極優 |
| 動態代理性能 | 優 | 優 |
| 配置靈活性 | XML 風格,模塊豐富 | 簡潔聲明式,正則強大 |
| 會話保持 | 原生 stickysession 完善 | 需 ip_hash/cookie/sticky 模塊 |
| 健康檢查 | mod_proxy_hcheck (2.4+) | max_fails/fail_timeout + 第三方模塊 |
| 內存佔用 | 較高 | 極低 |
| 推薦場景 | 既有 Apache 體系、需複雜認證/重寫 | 高並發、微服務網關、靜動分離 |
Apache mod_proxy_balancer 會話保持成熟,適合傳統 Java 應用;Nginx upstream 配合模塊化配置、靜態資源分離、長連接池,是現代高並發架構首選。生產環境建議:Nginx 做七層網關 + 靜態分離 + 限流熔斷,Tomcat 專注業務邏輯。配置納入版本控制、變更走發布流程、監控覆蓋上游健康狀態,構建可觀測、可演進的負載均衡層。