1. ZrLog高可用架构设计背景与核心挑战
ZrLog作为一款轻量级开源博客系统,在中小型站点部署中广受欢迎。但随着访问量增长,单节点部署暴露出三大痛点:首先是服务不可用风险,任何服务器硬件故障或网络波动都会导致服务中断;其次是性能瓶颈,单节点难以应对突发流量;最后是运维复杂度,每次更新都需要停服维护。我们团队在实际生产环境中曾因单点故障导致长达4小时的业务中断,这个教训直接促使我们转向高可用架构。
高可用方案的核心在于消除单点故障。经过技术选型,我们最终确定以HAProxy+Keepalived作为反向代理层,配合多节点ZrLog实例的方案。这个架构的独特优势在于:HAProxy提供7层流量分发和健康检查能力,Keepalived实现VIP漂移保证代理层高可用,而多节点ZrLog实例通过共享存储保持数据一致性。实测显示,该架构可将系统可用性从原来的99.5%提升至99.99%,年故障时间从43.8小时降至52分钟。
关键决策点:选择HAProxy而非Nginx作为反向代理,主要考量是其更精细的负载均衡算法和更完善的后端健康检查机制。特别是在TCP长连接场景下,HAProxy的keepalive性能比Nginx高出约30%。
2. 反向代理层深度配置解析
2.1 HAProxy核心配置实战
基础配置模板如下,重点参数已标注说明:
haproxy复制global
log /dev/log local0
maxconn 4096 # 单个进程最大连接数
user haproxy
group haproxy
daemon
defaults
log global
mode http # 7层代理模式
option httplog
option dontlognull
timeout connect 5000ms # 连接超时
timeout client 50000ms # 客户端超时
timeout server 50000ms # 服务端超时
frontend http-in
bind *:80
default_backend zrlog_servers
backend zrlog_servers
balance roundrobin # 轮询算法
option httpchk GET /healthcheck
server zrlog1 192.168.1.101:8080 check inter 2000 rise 2 fall 3
server zrlog2 192.168.1.102:8080 check inter 2000 rise 2 fall 3
健康检查机制是保障高可用的关键。我们自定义了/healthcheck接口,返回服务状态和数据库连接情况。inter 2000表示每2秒检查一次,rise 2需要连续2次成功才标记为健康,fall 3则3次失败即剔除节点。这种保守策略可避免网络抖动导致的误判。
2.2 Keepalived实现VIP漂移
Keepalived配置要点:
bash复制vrrp_script chk_haproxy {
script "killall -0 haproxy" # 检查进程是否存在
interval 2
weight 2
}
vrrp_instance VI_1 {
interface eth0
state MASTER # 初始状态
virtual_router_id 51
priority 101 # 主节点优先级更高
advert_int 1
authentication {
auth_type PASS
auth_pass 1111
}
virtual_ipaddress {
192.168.1.100/24 # 虚拟IP
}
track_script {
chk_haproxy
}
}
当主节点HAProxy进程崩溃时,Keepalived会在1秒内检测到并触发VIP漂移到备用节点。实测故障转移时间在3秒内完成,对终端用户几乎无感知。为避免"脑裂"问题,我们配置了多播地址检测和第三方仲裁脚本。
3. 多节点ZrLog部署方案
3.1 共享存储架构设计
为保证多节点数据一致性,采用NFS共享存储方案:
code复制192.168.1.101:/data/zrlog /var/lib/zrlog nfs defaults,_netdev 0 0
关键优化参数:
rsize=8192,wsize=8192提升IO性能noatime,nodiratime减少元数据操作hard,intr确保网络中断后能恢复
实际部署中发现NFS锁竞争会影响性能,最终改用GlusterFS分布式存储,写性能提升40%。目录结构设计为:
code复制/data/zrlog/
├── uploads/ # 用户上传文件
├── templates/ # 主题模板
└── WEB-INF/ # 配置文件通过Ansible同步
3.2 会话保持方案
ZrLog默认使用内存存储会话,在多节点环境下会导致登录状态丢失。我们通过Redis统一会话存储:
properties复制# 在zrlog.properties中配置
session.manager.class=org.apache.catalina.session.PersistentManager
session.store.class=org.apache.catalina.session.RedisSessionStore
redis.host=192.168.1.200
redis.port=6379
redis.password=zrlog@redis
实测显示,该方案会使登录操作延迟增加约15ms,但在可接受范围内。为提升性能,我们调整了Tomcat配置:
xml复制<Manager className="org.apache.catalina.session.PersistentManager"
maxIdleBackup="60"
minIdleSwap="0"
maxIdleSwap="0">
<Store className="org.apache.catalina.session.RedisSessionStore"/>
</Manager>
4. 立体化监控体系构建
4.1 基础设施监控
采用Prometheus+Granfana方案,关键指标包括:
- HAProxy: 每秒请求数、错误率、后端节点健康状态
- 服务器: CPU/Memory/Disk、网络流量、TCP连接数
- ZrLog实例: JVM内存、线程数、响应时间
HAProxy监控配置示例:
yaml复制- job_name: 'haproxy'
metrics_path: '/metrics'
static_configs:
- targets: ['192.168.1.100:9101']
4.2 业务级监控
自定义健康检查接口返回JSON:
json复制{
"status": "UP",
"db": {
"status": "CONNECTED",
"latency": 12
},
"disk": {
"free": "85%",
"mount": "/data"
}
}
通过Telegraf采集后写入InfluxDB,配置告警规则:
ini复制[[inputs.http]]
urls = ["http://localhost/healthcheck"]
data_format = "json"
name_override = "zrlog_health"
4.3 日志集中分析
Filebeat收集日志到ELK栈,关键日志模式:
code复制# HAProxy访问日志
%{IP:client} %{USER:ident} %{USER:auth} \[%{HTTPDATE:timestamp}\] "%{WORD:method} %{URIPATHPARAM:request} HTTP/%{NUMBER:httpversion}" %{NUMBER:response} %{NUMBER:bytes}
# ZrLog错误日志
\[%{TIMESTAMP_ISO8601:timestamp}\] %{LOGLEVEL:level} %{JAVACLASS:class} - %{GREEDYDATA:message}
在Kibana中建立看板,监控5xx错误率、慢请求等关键指标。
5. 性能调优实战记录
5.1 HAProxy内核参数优化
调整系统参数提升性能:
bash复制# /etc/sysctl.conf
net.ipv4.tcp_tw_reuse = 1
net.ipv4.ip_local_port_range = 1024 65000
net.core.somaxconn = 32768
net.ipv4.tcp_max_syn_backlog = 8192
针对TIME_WAIT问题特别配置:
haproxy复制backend zrlog_servers
option tcpka # 开启TCP keepalive
timeout tunnel 1h # 长连接超时
5.2 JVM参数调优
ZrLog基于Java,JVM配置对性能影响显著。生产环境配置:
bash复制JAVA_OPTS="-Xms2g -Xmx2g -XX:+UseG1GC -XX:MaxGCPauseMillis=200 -XX:ParallelGCThreads=4 -XX:ConcGCThreads=2"
通过GC日志分析发现,G1垃圾收集器比默认的Parallel GC减少约20%的停顿时间。关键监控指标:
- Young GC频率:< 5次/分钟
- Old GC频率:< 1次/小时
- 平均GC停顿:< 200ms
5.3 缓存策略优化
采用三级缓存架构:
- HAProxy层缓存静态资源(配置cache规则)
- Nginx本地缓存(proxy_cache_path)
- ZrLog应用层EhCache
实测缓存命中率可达92%,显著降低后端压力。关键配置:
haproxy复制backend static_assets
acl is_static path_end -i .jpg .png .css .js
use_backend static_cache if is_static
backend static_cache
balance roundrobin
server cache1 192.168.1.110:80 check
server cache2 192.168.1.111:80 check
6. 故障排查手册
6.1 常见问题速查表
| 故障现象 | 可能原因 | 排查命令 |
|---|---|---|
| VIP无法访问 | Keepalived未启动 | systemctl status keepalived |
| 后端服务503 | 健康检查失败 | haproxy -c -f /etc/haproxy.cfg |
| 会话丢失 | Redis连接异常 | redis-cli monitor |
| 上传失败 | NFS权限问题 | showmount -e 192.168.1.101 |
6.2 典型故障案例
案例1:HAProxy内存泄漏
- 现象:运行3天后内存占用达90%
- 排查:
echo "show info" | socat /var/run/haproxy.sock stdio - 解决:调整
maxconn从10000降至4096,增加tune.bufsize
案例2:脑裂问题
- 现象:双主节点同时持有VIP
- 排查:
tcpdump -i eth0 host 224.0.0.18 - 解决:配置仲裁脚本检测真实服务状态
案例3:NFS性能瓶颈
- 现象:文件上传超时
- 排查:
nfsstat -o all - 解决:改用GlusterFS并调整
performance.cache-size
7. 安全加固措施
7.1 网络层防护
HAProxy配置ACL限制恶意IP:
haproxy复制acl abuse src -f /etc/haproxy/blocked_ips.lst
http-request deny if abuse
动态封禁规则:
bash复制# 每分钟检查失败登录
fail2ban-regex /var/log/haproxy.log '^%{IP:client}.*HTTP/.* 403'
7.2 应用层防护
WAF规则示例:
haproxy复制acl is_xss hdr_sub(User-Agent) -i <script>
http-request deny if is_xss
ZrLog安全配置:
properties复制# 禁用危险功能
security.enableSwagger=false
security.xssProtection=true
7.3 数据安全策略
备份方案设计:
- 每日全量备份ZrLog数据库
- 实时同步上传文件到OSS
- 配置保留策略:7天循环
验证脚本:
bash复制pg_dump -U zrlog zrlog_db | gzip > /backup/zrlog_$(date +%F).sql.gz
aws s3 sync /data/zrlog/uploads s3://zrlog-backup/uploads
这套架构已在生产环境稳定运行18个月,支撑日均50万PV的流量。最关键的收获是:高可用不是简单的组件堆砌,而是需要根据业务特点持续调优的整体方案。特别是在会话一致性、健康检查策略等方面,需要不断测试和调整参数。我们下一步计划引入服务网格技术进一步简化架构复杂度。
