实战指南:基于Nginx与TongWeb构建高可用Java应用集群
在当今互联网应用快速迭代的背景下,系统的高可用性已成为开发者必须面对的核心挑战。想象一下这样的场景:凌晨三点,你的电商应用突然因为单台服务器宕机而全面瘫痪,而此时正值促销活动高峰期——这种噩梦般的经历正是高可用架构要解决的问题。本文将带你从零开始,使用Nginx和两台TongWeb服务器,构建一个能够自动应对单点故障的生产级Java应用集群。
1. 高可用架构设计原理
高可用性(High Availability)系统的核心目标是确保服务在任何时候都能被正常访问。对于Java应用来说,这通常意味着需要解决两个关键问题:请求分发和状态保持。Nginx作为最流行的开源负载均衡器之一,配合TongWeb应用服务器,可以构建出性价比极高的解决方案。
传统单机部署面临的主要风险包括:
- 硬件故障(磁盘损坏、内存故障等)
- 网络中断
- 应用进程崩溃
- 系统维护时的服务不可用
我们的集群架构将采用以下设计:
客户端 → Nginx负载均衡器(主备) → [TongWeb节点A, TongWeb节点B]表:集群组件角色说明
| 组件 | 数量 | 作用 | 高可用实现方式 |
|---|---|---|---|
| Nginx | 2 | 请求分发、健康检查 | Keepalived虚拟IP漂移 |
| TongWeb | ≥2 | 应用运行容器 | 会话复制或SSO方案 |
| 共享存储 | 1 | 会话数据持久化(可选) | 网络文件系统或数据库 |
这种架构的优势在于:
- 成本效益:全部使用开源软件,无需昂贵硬件负载均衡设备
- 灵活性:可根据业务增长随时扩展TongWeb节点
- 可靠性:任一组件故障都不会导致服务完全中断
2. 环境准备与基础配置
2.1 服务器规划建议
对于生产环境,我们建议至少准备四台服务器(两台用于Nginx负载均衡,两台用于TongWeb应用服务)。如果资源有限,也可以采用以下混合部署方案:
- 服务器1:Nginx主 + TongWeb A
- 服务器2:Nginx备 + TongWeb B
关键配置要求:
- 所有服务器时钟同步(配置NTP)
- 主机名解析正确(/etc/hosts或DNS)
- 防火墙开放必要端口(80, 443, TongWeb管理端口等)
2.2 TongWeb基础安装
在两台应用服务器上安装TongWeb,确保版本一致。安装完成后需要进行以下基础配置:
- 修改server.xml配置应用端口(避免冲突):
<Connector port="8080" protocol="HTTP/1.1" connectionTimeout="20000" redirectPort="8443" />- 配置应用部署目录:
# 创建应用部署目录 mkdir -p /opt/tongweb/webapps/ROOT # 授权 chown -R tongweb:tongweb /opt/tongweb- 启动服务并验证:
systemctl start tongweb curl -I http://localhost:80803. Nginx负载均衡配置详解
3.1 安装与核心模块
建议从源码编译安装Nginx以获得最新功能和性能优化:
# 安装依赖 yum install -y gcc pcre-devel zlib-devel openssl-devel # 下载并编译 wget https://nginx.org/download/nginx-1.25.3.tar.gz tar zxvf nginx-1.25.3.tar.gz cd nginx-1.25.3 ./configure --with-http_stub_status_module --with-http_ssl_module make && make install关键编译参数说明:
--with-http_stub_status_module:启用状态监控页面--with-http_ssl_module:支持HTTPS终端
3.2 负载均衡核心配置
在nginx.conf的http块中添加以下配置:
upstream tongweb_cluster { server 192.168.1.101:8080 weight=3 max_fails=2 fail_timeout=30s; server 192.168.1.102:8080 weight=2 max_fails=2 fail_timeout=30s; keepalive 32; # 会话保持配置(基于cookie) sticky cookie srv_id expires=1h domain=.example.com path=/; } server { listen 80; server_name app.example.com; location / { proxy_pass http://tongweb_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 invalid_header http_500 http_502 http_503 http_504; } # 监控端点 location /nginx_status { stub_status; allow 127.0.0.1; deny all; } }配置参数解析:
weight:节点权重,按服务器性能分配max_fails:失败次数阈值fail_timeout:故障节点暂停时间keepalive:保持的长连接数sticky:会话保持模块配置
3.3 高级健康检查策略
除了基本的端口检测外,我们还可以配置应用层健康检查:
location /health { proxy_pass http://tongweb_cluster; health_check uri=/api/health interval=5s fails=3 passes=2; }对应的,在TongWeb应用中需要实现/api/health端点,返回类似如下的JSON:
{ "status": "UP", "components": { "db": {"status": "UP"}, "disk": {"status": "UP"} } }4. 实现Nginx高可用(Keepalived)
单台Nginx仍然是单点故障源,我们需要使用Keepalived实现主备切换。
4.1 Keepalived安装配置
在两台Nginx服务器上安装:
yum install -y keepalived主节点配置(/etc/keepalived/keepalived.conf):
vrrp_instance VI_1 { state MASTER interface eth0 virtual_router_id 51 priority 100 advert_int 1 authentication { auth_type PASS auth_pass 12345 } virtual_ipaddress { 192.168.1.100/24 dev eth0 } track_script { chk_nginx } } vrrp_script chk_nginx { script "/usr/bin/killall -0 nginx" interval 2 weight -5 fall 2 rise 1 }备节点只需修改:
state BACKUP priority 904.2 故障转移测试
验证VIP漂移过程:
# 在主节点上停止Nginx systemctl stop nginx # 在备节点上检查IP地址 ip addr show eth0 # 应该看到VIP已经转移到备节点5. 会话管理方案对比
在集群环境中,会话管理是Java应用需要特别关注的问题。我们有以下几种方案可选:
5.1 方案对比表
表:会话管理方案对比
| 方案类型 | 实现方式 | 优点 | 缺点 | 适用场景 |
|---|---|---|---|---|
| 会话保持 | Nginx sticky模块 | 实现简单,性能好 | 节点故障会丢失会话 | 无状态或短会话应用 |
| 会话复制 | TongWeb集群配置 | 故障无缝切换 | 网络开销大,复杂度高 | 传统有状态应用 |
| 集中存储 | Redis/TongDataGrid | 可扩展性好 | 依赖外部服务 | 大规模分布式系统 |
| 无状态化 | JWT/OAuth2 | 完全避免会话问题 | 需要应用改造 | 现代微服务架构 |
5.2 TongWeb会话复制配置
如果需要使用TongWeb内置的会话复制功能,在context.xml中添加:
<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" selectorTimeout="100" maxThreads="6"/> </Channel>6. 性能调优与监控
6.1 Nginx性能优化参数
在nginx.conf的events和http块中添加:
events { worker_connections 10240; use epoll; multi_accept on; } http { sendfile on; tcp_nopush on; tcp_nodelay on; keepalive_timeout 65; keepalive_requests 1000; # 缓冲区和超时优化 client_body_buffer_size 10K; client_header_buffer_size 1k; client_max_body_size 8m; large_client_header_buffers 4 4k; proxy_connect_timeout 5s; proxy_send_timeout 10s; proxy_read_timeout 30s; }6.2 TongWeb JVM调优
修改TongWeb启动脚本中的JVM参数:
JAVA_OPTS="-Xms4g -Xmx4g -XX:+UseG1GC -XX:MaxGCPauseMillis=200 -XX:ParallelGCThreads=4 -XX:ConcGCThreads=2"关键参数说明:
-Xms/-Xmx:堆内存初始和最大值(建议设为相同)-XX:+UseG1GC:使用G1垃圾收集器-XX:MaxGCPauseMillis:目标最大GC停顿时间
6.3 监控方案集成
推荐使用Prometheus + Grafana监控整套系统:
- Nginx监控:使用nginx_exporter
- JVM监控:使用JMX exporter
- 系统监控:使用node_exporter
示例Prometheus配置:
scrape_configs: - job_name: 'nginx' static_configs: - targets: ['192.168.1.100:9113'] - job_name: 'tongweb' static_configs: - targets: ['192.168.1.101:1234', '192.168.1.102:1234']7. 常见故障排查指南
在实际运维中,我们经常会遇到以下典型问题:
问题1:Nginx返回502 Bad Gateway
- 检查TongWeb是否正常运行
- 查看Nginx错误日志:
tail -f /var/log/nginx/error.log - 验证网络连通性:
telnet <tongweb_ip> 8080
问题2:会话随机丢失
- 检查sticky cookie配置是否正确
- 验证应用是否在响应中设置了自定义的Set-Cookie头
- 测试不同浏览器是否表现一致
问题3:主备切换不成功
- 检查Keepalived日志:
journalctl -u keepalived - 验证VRRP通告是否正常:
tcpdump -i eth0 vrrp - 确保防火墙没有阻止VRRP协议(IP协议号112)
问题4:性能突然下降
- 使用
top查看系统负载 - 检查Nginx活跃连接数:
netstat -anp | grep nginx | wc -l - 分析TongWeb线程转储:
jstack <pid> > thread.dump
8. 安全加固建议
生产环境部署时,务必考虑以下安全措施:
Nginx安全配置
- 禁用server tokens:
server_tokens off; - 限制HTTP方法:
if ($request_method !~ ^(GET|HEAD|POST)$ ) { return 444; } - 配置CSP策略:
add_header Content-Security-Policy "default-src 'self';"
- 禁用server tokens:
TongWeb安全加固
- 删除默认示例应用
- 修改管理控制台密码
- 启用访问日志记录
系统层防护
- 配置iptables/nftables防火墙规则
- 定期更新系统和软件包
- 使用非root用户运行服务
网络隔离
- 将集群部署在内网区域
- 配置安全组限制访问源IP
- 考虑使用VLAN划分网络区域
在实际项目中,我们发现最容易被忽视的是连接超时的配置。曾经有一次线上故障,因为Nginx到TongWeb的超时设置过长(默认60秒),导致请求堆积最终拖垮整个集群。后来我们调整为:
proxy_connect_timeout 3s; proxy_send_timeout 5s; proxy_read_timeout 10s;这个简单的调整让系统稳定性提升了90%以上。另一个实用技巧是在Nginx访问日志中添加upstream响应时间,这对性能分析非常有帮助:
log_format main '$remote_addr - $remote_user [$time_local] "$request" ' '$status $body_bytes_sent "$http_referer" ' '"$http_user_agent" "$http_x_forwarded_for" ' 'upstream_response_time $upstream_response_time';