Java在Linux上的高可用实现路径
一、总体架构与分层
- 接入层:使用Nginx/HAProxy做反向代理与负载均衡,支持健康检查与故障摘除,避免单点。
- 应用层:多实例部署Java服务(如 Spring Boot),实例间无状态,支持水平扩展与滚动升级。
- 数据层:数据库与缓存采用主从/集群与故障切换策略,避免数据库成为单点。
- 运行时保障:用systemd保证进程异常退出能自动拉起;必要时引入Keepalived VIP做主备漂移。
- 观测与告警:接入Prometheus + Grafana监控与ELK日志,设置告警规则,快速定位与恢复。
二、单机进程自恢复与快速落地 systemd
- 适用场景:单台机器上保证进程“崩溃即重启”,并具备开机自启与日志归集。
- 核心配置示例(/etc/systemd/system/myapp.service):
[Unit]
Description=My Java App
After=network.target
[Service]
Type=simple
User=appuser
WorkingDirectory=/opt/myapp
ExecStart=/usr/bin/java -Xms512m -Xmx1g -jar /opt/myapp/app.jar --server.port=8080
SuccessExitStatus=143
Restart=on-failure
RestartSec=10
RestartMaxDelaySec=900
StartLimitInterval=300
StartLimitBurst=5
StandardOutput=append:/var/log/myapp/stdout.log
StandardError=append:/var/log/myapp/stderr.log
[Install]
WantedBy=multi-user.target
- 常用命令:
- 重载配置:sudo systemctl daemon-reload
- 启动/停止/重启:systemctl start|stop|restart myapp
- 开机自启:systemctl enable myapp
- 查看状态/日志:systemctl status myapp;journalctl -u myapp -f
- 自动重启触发与不触发要点:
- 触发:异常退出(非0)、未捕获异常导致崩溃、OOM、被信号终止等。
- 不触发:systemctl stop、手动 kill、系统关机。
三、多实例与负载均衡
- 多实例部署:同一应用在多台Linux节点各启动一个或多个实例(不同端口或不同主机),保持无状态或外部化会话。
- Nginx 负载均衡示例(/etc/nginx/conf.d/app.conf):
upstream backend {
server 10.0.1.11:8080 max_fails=3 fail_timeout=30s;
server 10.0.1.12:8080 max_fails=3 fail_timeout=30s;
server 10.0.1.13:8080 max_fails=3 fail_timeout=30s;
}
server {
listen 80;
location / {
proxy_pass http://backend;
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;
}
}
- 要点:开启健康检查(max_fails/fail_timeout)、会话保持策略(如基于 cookie/header)、连接复用与超时调优。
四、主备容灾与VIP漂移 Keepalived
- 适用场景:需要对外暴露单一VIP且容忍N-1故障的接入场景(如传统单体或无法横向扩展的服务)。
- 基本思路:两台或多台主机运行相同 Java 服务,通过Keepalived管理虚拟IP(VIP);主机/进程异常时降低优先级或移除路由,实现VIP漂移。
- 关键配置要点(示例):
- state:一台为MASTER、其余为BACKUP
- priority:MASTER 高于 BACKUP(如 100 vs 99)
- virtual_router_id:同一组保持一致
- authentication:设置共享口令
- track_script/接口:检测 Java 进程或端口存活,失败则降级
- virtual_ipaddress:对外统一 VIP
- 健康脚本示例(/opt/check_tomcat.sh):
#!/usr/bin/env bash
if ! pgrep -x "java" >/dev/null; then
systemctl stop keepalived # 触发切换
fi
- 适用提醒:主备方案提供故障转移能力,但整体容量与并发受限于单台实例;优先采用“多实例+负载均衡”的Active-Active模式。
五、数据层、监控与常见故障处理
- 数据层高可用:
- 数据库:部署主从复制/集群(如 MySQL 主从、MGR 或 Pg 流复制),读写分离与故障切换。
- 缓存:使用Redis 集群/哨兵或 Memcached 集群,避免缓存单点。
- 消息队列:采用Kafka/RabbitMQ集群,保障消息可靠与可恢复。
- 监控与日志:
- 指标与可视化:Prometheus 采集应用与系统指标,Grafana 展示与告警面板。
- 日志集中:ELK(Elasticsearch/Logstash/Kibana) 统一收集与分析日志,便于快速排障。
- 常见故障与对策:
- 内存不足/被 OOM Killer 终止:优化代码与对象生命周期,合理设置 -Xms/-Xmx,必要时开启 -XX:+HeapDumpOnOutOfMemoryError 分析;监控内存使用并设置告警。
- 进程异常退出:依赖 systemd Restart=on-failure 自动拉起,配合健康检查摘除异常实例。
- 单实例瓶颈:横向扩容实例数,接入层健康检测与熔断,避免雪崩。