1. 高可用架构的选型逻辑与核心思路拆解做运维这行十来年被问得最多的一类问题就是“我这套服务怎么才能不宕机”不管是电商的订单接口、内部用的管理系统还是给客户交付的私有化部署只要涉及到线上业务高可用就是绕不过去的一道坎。今天要聊的这套组合——Keepalived热备、KeepalivedLVS、HAProxy——基本上就是中小规模高可用架构里最经典的三板斧。它们各自解决不同层面的问题但经常被混在一起用也经常被用错。先说清楚这三个东西各自是干什么的不然后面全是糊涂账。Keepalived的核心能力是VRRP协议实现的IP漂移也就是我们常说的“虚拟IP”。两台机器一主一备主挂了VIP自动飘到备机上客户端完全无感知。它解决的是“单点故障”问题但注意它本身不负责流量分发也不管后端服务死活它只管自己这一层的IP在不在。LVS是四层负载均衡工作在内核态性能极高抗并发能力强。它把请求转发给后端真实服务器支持NAT、DR、TUN等多种模式。LVS本身没有健康检查的完整能力所以通常要配合Keepalived一起用——Keepalived负责VIP漂移和RS健康检查LVS负责转发。HAProxy是七层负载均衡能解析HTTP协议支持基于URL、Header、Cookie的精细化调度还能做SSL卸载、会话保持、限流等。它的健康检查比LVS丰富得多配置也更灵活但性能上限不如LVS毕竟工作在用户态。所以选型逻辑其实很清晰四层用LVS扛量七层用HAProxy做精细调度Keepalived给它们做高可用。三者不是替代关系而是不同层次的互补。很多新手一上来就问“LVS和HAProxy哪个好”这个问题本身就问错了——它们解决的不是同一个问题。我见过不少项目明明QPS只有几百非要上LVSKeepalived全套结果配置复杂、排查困难运维成本远超收益。也见过日活几十万的系统只用了一台HAProxy挂了就全挂。所以架构选型的第一原则是匹配业务规模不要为了技术而技术。下面这张表是我自己总结的选型参考可以直接对照自己的场景场景特征推荐方案理由单机服务要求故障自动切换Keepalived双机热备最简单VIP漂移即可四层TCP服务高并发KeepalivedLVS(DR模式)内核态转发性能最优HTTP服务需要按URL调度KeepalivedHAProxy七层解析灵活超大规模多层架构LVSHAProxyKeepalived四层扛量七层调度预算有限只有两台机器KeepalivedHAProxy一机双角色够用这张表不是死的实际项目里经常要根据机器数量、团队技术栈、预算来调整。但核心思路不变先明确你要解决的是IP单点、流量分发、还是协议解析再决定用哪个组件。还有一个容易被忽略的点高可用架构的复杂度是呈指数上升的。两台机器做Keepalived配置量是1加上LVS配置量变成3再加上HAProxy做后端配置量变成5而且排查链路变长。所以我的建议是能用简单方案解决的绝不上复杂方案。很多场景下KeepalivedHAProxy两台机器就能撑住没必要引入LVS。2. Keepalived热备的核心细节与实操要点Keepalived热备是整个高可用体系的地基地基打不牢上面盖什么都是白搭。这一块我踩过的坑最多所以展开讲细一点。2.1 VRRP协议与VIP漂移原理Keepalived的核心是VRRPVirtual Router Redundancy Protocol。简单说就是两台机器组成一个虚拟路由器对外暴露一个虚拟IP。同一时刻只有一台机器MASTER持有这个VIP并响应ARP请求另一台BACKUP处于待命状态。MASTER定期发送VRRP通告报文BACKUP收不到就认为MASTER挂了自己接管VIP。这里有个关键参数叫advert_int默认1秒意思是MASTER每秒发一次心跳。BACKUP如果连续3个周期3秒收不到就触发切换。这个值可以调但不要调太小否则网络抖动容易误切换也不要调太大否则故障切换太慢。生产环境一般保持1秒配合3次超时切换时间在3秒左右大部分业务能接受。另一个关键参数是priority优先级。MASTER的priority要比BACKUP高默认100可以设成101和100。如果两台一样会先起来的当MASTER容易出问题所以一定要显式设置不同的优先级。VIP漂移的本质是免费ARPGratuitous ARP。新MASTER接管VIP后会向局域网广播一个ARP包告诉所有设备“这个IP现在在我这”交换机和其它主机会更新ARP缓存表后续流量就发到新MASTER了。这个过程通常在毫秒级完成客户端基本无感知。2.2 双机热备的完整配置下面是我在实际项目里用的配置模板主备两台机器以Nginx服务为例。先看MASTER的配置# /etc/keepalived/keepalived.conf global_defs { router_id LVS_MASTER_01 script_user root enable_script_security } vrrp_script chk_nginx { script /etc/keepalived/check_nginx.sh interval 2 weight -20 fall 2 rise 2 } vrrp_instance VI_1 { state MASTER interface eth0 virtual_router_id 51 priority 101 advert_int 1 authentication { auth_type PASS auth_pass MySecurePass2024 } virtual_ipaddress { 192.168.10.100/24 dev eth0 label eth0:1 } track_script { chk_nginx } notify_master /etc/keepalived/notify.sh master notify_backup /etc/keepalived/notify.sh backup notify_fault /etc/keepalived/notify.sh fault }BACKUP的配置只有三处不同router_id、state改成BACKUP、priority改成100。其它完全一致。这里有几个细节必须说清楚virtual_router_id是VRRP组的标识同一个组的主备必须一致不同组必须不同。范围1-255我一般用51、52这种避开默认值。如果同一个网络里有多个Keepalived集群VRID冲突会导致VIP乱飘这是新手最容易踩的坑。authentication认证虽然简单但一定要设而且主备必须一致。不设认证的话任何一台机器都能加入这个VRRP组安全隐患很大。track_script是健康检查脚本这是Keepalived真正实用的地方。光靠VRRP心跳只能检测机器是否存活检测不了服务是否正常。比如Nginx进程还在但已经卡死无法响应请求这时候VRRP心跳还是正常的不会切换。加上track_script脚本检测到Nginx异常就动态降低优先级触发切换。健康检查脚本长这样#!/bin/bash # /etc/keepalived/check_nginx.sh counter$(ps -C nginx --no-heading | wc -l) if [ ${counter} -eq 0 ]; then exit 1 fi # 进一步检测端口是否可访问 curl -s -o /dev/null -w %{http_code} http://127.0.0.1:80/health | grep -q 200 if [ $? -ne 0 ]; then exit 1 fi exit 0脚本返回0表示健康非0表示异常。配合weight -20异常时优先级从101降到81低于BACKUP的100触发切换。fall 2表示连续失败2次才判定异常rise 2表示连续成功2次才恢复避免抖动误判。注意脚本必须有可执行权限而且Keepalived默认以root运行脚本脚本里不要做危险操作。另外脚本执行时间不能超过interval否则会堆积。2.3 脑裂问题与防护脑裂是高可用架构里最危险的情况主备之间网络断了但两台机器都活着都认为对方挂了于是都抢着持有VIP。结果就是同一个VIP出现在两台机器上客户端请求一半到主一半到备数据错乱后果严重。防护手段有几个第一用独立的心跳线。主备之间除了业务网卡再拉一根网线专门跑VRRP心跳。这样即使业务网络故障心跳线还在不会误判。这是最有效的方案但需要额外网卡。第二配置unicast_peer。默认VRRP用组播改成单播指定对端IP减少误判unicast_src_ip 192.168.10.11 unicast_peer { 192.168.10.12 }第三加fence机制。检测到脑裂时直接关机或切断网络保证只有一台机器持有VIP。这个比较暴力但有效。第四监控告警。无论如何都要对VIP做监控一旦发现同一个VIP出现在两台机器上立即告警人工介入。我个人的经验是小规模用单播监控就够了大规模一定要上独立心跳线。脑裂的代价太大不值得赌。3. KeepalivedLVS四层负载均衡实战LVS是四层负载均衡的王者性能没得说但配置和排查确实有点门槛。这一章把DR模式的完整搭建过程讲透。3.1 LVS三种模式的取舍LVS有三种工作模式选错了后面全是坑NAT模式请求和响应都经过LVSLVS是瓶颈而且后端RS的网关要指向LVS。适合小规模配置简单但性能差。DR模式LVS只改MAC地址响应直接由RS返回给客户端LVS不参与回程流量。性能最高是生产环境首选。但要求LVS和RS在同一个二层网络而且RS要配置VIP在lo上并抑制ARP。TUN模式IP隧道支持跨机房但需要RS支持隧道协议配置复杂实际用得少。生产环境90%的场景用DR模式所以下面重点讲DR。3.2 DR模式完整搭建步骤假设环境如下LVS主192.168.10.11LVS备192.168.10.12VIP192.168.10.100RS1192.168.10.21RS2192.168.10.22第一步LVS主备安装Keepalived和ipvsadmyum install -y keepalived ipvsadm第二步配置LVS主的Keepalived# /etc/keepalived/keepalived.conf global_defs { router_id LVS_MASTER } vrrp_instance VI_1 { state MASTER interface eth0 virtual_router_id 51 priority 101 advert_int 1 authentication { auth_type PASS auth_pass LvsPass2024 } virtual_ipaddress { 192.168.10.100/24 dev eth0 label eth0:1 } } virtual_server 192.168.10.100 80 { delay_loop 6 lb_algo wrr lb_kind DR persistence_timeout 50 protocol TCP real_server 192.168.10.21 80 { weight 1 TCP_CHECK { connect_timeout 3 nb_get_retry 3 delay_before_retry 3 connect_port 80 } } real_server 192.168.10.22 80 { weight 1 TCP_CHECK { connect_timeout 3 nb_get_retry 3 delay_before_retry 3 connect_port 80 } } }备机配置把state改成BACKUPpriority改成100router_id改成LVS_BACKUP。第三步RS配置VIP和ARP抑制。这是DR模式最关键的一步配错了整个架构就废了。在每台RS上执行# 创建VIP绑定脚本 /etc/init.d/realserver #!/bin/bash VIP192.168.10.100 case $1 in start) ifconfig lo:0 $VIP netmask 255.255.255.255 broadcast $VIP /sbin/route add -host $VIP dev lo:0 echo 1 /proc/sys/net/ipv4/conf/lo/arp_ignore echo 2 /proc/sys/net/ipv4/conf/lo/arp_announce echo 1 /proc/sys/net/ipv4/conf/all/arp_ignore echo 2 /proc/sys/net/ipv4/conf/all/arp_announce sysctl -p /dev/null 21 ;; stop) ifconfig lo:0 down echo 0 /proc/sys/net/ipv4/conf/lo/arp_ignore echo 0 /proc/sys/net/ipv4/conf/lo/arp_announce echo 0 /proc/sys/net/ipv4/conf/all/arp_ignore echo 0 /proc/sys/net/ipv4/conf/all/arp_announce ;; *) echo Usage: $0 {start|stop} exit 1 esac这里解释一下两个关键参数arp_ignore1只回答目标IP是本机网卡IP的ARP请求。这样当别人问“谁是192.168.10.100”时RS不会用eth0的MAC去回答避免抢VIP。arp_announce2发送ARP时使用最合适的源IP。防止RS用VIP作为源IP发ARP干扰网络。这两个参数不配VIP会被RS抢走LVS就失效了。这是DR模式最经典的坑。第四步启动验证systemctl start keepalived ipvsadm -Ln正常应该看到VIP和两台RS的转发规则。然后在客户端访问VIP看请求是否轮询到两台RS。3.3 LVS调度算法选择LVS支持多种调度算法常用的有算法说明适用场景rr轮询后端性能一致wrr加权轮询后端性能有差异lc最少连接长连接场景wlc加权最少连接通用推荐sh源地址哈希需要会话保持dh目标地址哈希缓存场景我一般用wrr或wlc。wrr适合后端配置不同的情况wlc适合长连接。如果业务需要会话保持可以用sh但更推荐在应用层做session共享而不是依赖LVS的会话保持。注意persistence_timeout是会话保持时间单位秒。设了之后同一客户端在超时时间内会一直转发到同一台RS。这个值不要设太大否则负载不均也不要太小否则会话丢失。50秒是个常用值。4. HAProxy七层负载均衡配置与调优HAProxy是我个人最喜欢的负载均衡器配置灵活功能强大日志清晰排查方便。这一章讲透它的核心配置和调优。4.1 HAProxy核心配置结构HAProxy的配置文件分四段global、defaults、frontend、backend。结构清晰但参数多容易看花眼。下面是一个生产级的配置模板# /etc/haproxy/haproxy.cfg global log 127.0.0.1 local0 info maxconn 65535 chroot /var/lib/haproxy user haproxy group haproxy daemon nbproc 4 cpu-map 1 0 cpu-map 2 1 cpu-map 3 2 cpu-map 4 3 stats socket /var/lib/haproxy/stats mode 600 level admin defaults log global mode http option httplog option dontlognull option http-server-close option forwardfor except 127.0.0.0/8 option redispatch retries 3 timeout http-request 10s timeout queue 1m timeout connect 5s timeout client 30s timeout server 30s timeout http-keep-alive 10s timeout check 5s maxconn 30000 frontend web_front bind *:80 bind *:443 ssl crt /etc/haproxy/certs/site.pem mode http option forwardfor acl is_api path_beg /api/ acl is_static path_beg /static/ use_backend api_servers if is_api use_backend static_servers if is_static default_backend web_servers backend web_servers mode http balance roundrobin option httpchk GET /health HTTP/1.1\r\nHost:\ www.example.com http-check expect status 200 server web1 192.168.10.21:80 check inter 2s rise 2 fall 3 weight 1 server web2 192.168.10.22:80 check inter 2s rise 2 fall 3 weight 1 backend api_servers mode http balance leastconn option httpchk GET /api/health http-check expect status 200 server api1 192.168.10.31:8080 check inter 2s rise 2 fall 3 server api2 192.168.10.32:8080 check inter 2s rise 2 fall 3 backend static_servers mode http balance source server static1 192.168.10.41:80 check server static2 192.168.10.42:80 check listen stats bind *:9000 mode http stats enable stats uri /haproxy-stats stats auth admin:StrongPass2024 stats refresh 10s这个配置里有几个关键点值得展开nbproc多进程HAProxy默认单进程多核CPU用不满。设nbproc为CPU核数配合cpu-map绑定能显著提升吞吐。但注意多进程模式下stats socket会有问题而且部分功能不支持所以现在更推荐用多线程模式HAProxy 1.8去掉nbproc设nbthread 4即可。timeout设置这是最容易出问题的地方。timeout connect是连接后端超时timeout client是客户端空闲超时timeout server是后端响应超时。设太短正常请求被断设太长慢请求堆积。我的经验是connect 5sclient/server 30shttp-request 10s基本能覆盖大部分场景。健康检查option httpchk发HTTP请求检测比TCP检测更准确。inter 2s每2秒检测一次rise 2连续2次成功才上线fall 3连续3次失败才下线。这个组合能有效避免抖动误判。4.2 会话保持的三种方案HTTP是无状态的但很多业务需要会话保持。HAProxy支持三种方式源IP哈希balance source同一客户端IP固定到同一后端。简单但NAT环境下大量用户共享IP会导致负载不均。Cookie插入cookie SERVERID insertHAProxy在响应里插入Cookie后续请求根据Cookie转发。最可靠但需要应用配合。粘性表stick-table基于各种维度做会话保持灵活但配置复杂。我一般推荐Cookie插入配置如下backend web_servers balance roundrobin cookie SERVERID insert indirect nocache server web1 192.168.10.21:80 check cookie web1 server web2 192.168.10.22:80 check cookie web2insert表示插入Cookieindirect表示客户端看不到后端信息nocache表示不缓存。这样同一用户的请求会一直转发到同一台后端。4.3 HAProxy性能调优参数HAProxy的性能调优核心是几个参数参数建议值说明maxconn(global)65535全局最大连接数maxconn(defaults)30000单实例最大连接nbthreadCPU核数多线程模式ulimit-n自动文件描述符限制tune.bufsize16384缓冲区大小tune.maxrewrite1024重写缓冲区系统层面还要调# /etc/security/limits.conf haproxy soft nofile 65535 haproxy hard nofile 65535 # /etc/sysctl.conf net.ipv4.tcp_tw_reuse 1 net.ipv4.ip_local_port_range 1024 65000 net.ipv4.tcp_max_syn_backlog 8192 net.core.somaxconn 32768这些参数不调HAProxy在高并发下会报“cannot allocate memory”或“too many open files”。注意tune.bufsize改小能省内存但可能影响大Header的请求改大能支持大Cookie但内存占用上升。默认16384够用不要乱改。5. 三层架构整合与故障排查实录前面三章分别讲了Keepalived、LVS、HAProxy这一章讲怎么把它们整合起来以及实际运维中的排查经验。5.1 完整架构拓扑与数据流一个典型的三层高可用架构是这样的最外层KeepalivedLVS两台机器VIP对外四层转发中间层HAProxy集群接收LVS转发的请求做七层调度最内层真实应用服务器处理业务数据流是客户端 → VIP → LVS → HAProxy → 应用服务器。这个架构的好处是LVS扛住四层高并发HAProxy做七层精细调度Keepalived保证每一层都不单点。但复杂度也上来了排查问题要一层层看。5.2 常见故障排查速查表下面这张表是我这些年攒下来的排查经验基本覆盖了90%的问题现象可能原因排查方法解决VIP不通Keepalived没启动ip addr看VIP在不在启动KeepalivedVIP双活脑裂两台都ip addr看检查心跳线加fenceLVS不转发RS的ARP没抑制ipvsadm -Ln看规则配arp_ignore请求全到一台RS调度算法或权重问题ipvsadm -Lnc看连接检查weight配置HAProxy 503后端全挂看HAProxy日志检查后端服务HAProxy 502后端返回异常看后端日志检查应用会话丢失会话保持没配看Cookie配cookie insert连接超时timeout太短看日志timeout调大timeout性能上不去单进程top看CPU开多线程文件描述符耗尽ulimit没调ulimit -n调大限制5.3 几个真实的排查案例案例一VIP漂移后客户端还是访问旧机器。这个问题的根源是ARP缓存。VIP漂移后新MASTER发了免费ARP但有些客户端或交换机的ARP缓存没更新还是把请求发到旧机器。解决办法是漂移脚本里主动发几次免费ARP或者调短ARP缓存时间。我在notify_master脚本里加了arping -c 3 -I eth0 -s VIP 网关IP基本能解决。案例二LVS转发正常但响应慢。排查发现是RS的回程路由问题。DR模式下RS的响应直接返回客户端不走LVS。如果RS的默认网关配置不对响应会走错路。检查RS的ip route确保默认网关是真实网关不是LVS。这个坑很隐蔽因为请求能通只是慢。案例三HAProxy日志显示大量503但后端正常。排查发现是健康检查太频繁后端扛不住。inter 2s意味着每2秒一次检查如果有100台后端每秒50次检查小后端直接被打挂。解决办法是调大inter或者用option httpchk的port参数指定一个轻量的健康检查端口。案例四Keepalived频繁切换。日志里全是“VRRP_Instance(VI_1) Transition to MASTER”。原因是网络抖动VRRP心跳丢包。解决办法是调大advert_int和fall或者用单播代替组播。我一般把advert_int设成1fall设成3基本能过滤掉大部分抖动。5.4 监控与告警配置高可用架构没有监控就是裸奔。必须监控的指标VIP是否在正确的机器上Keepalived进程是否存活LVS连接数是否异常HAProxy后端健康状态各层响应时间我一般用PrometheusAlertmanager配合keepalived_exporter、haproxy_exporter。关键告警规则- alert: VIPDoubleActive expr: count(keepalived_vip_status 1) by (vip) 1 for: 10s annotations: summary: VIP双活可能脑裂 - alert: HAProxyBackendDown expr: haproxy_backend_active_servers 1 for: 30s annotations: summary: HAProxy后端全部下线这两个告警一配基本能第一时间发现大问题。6. 架构演进与个人实操心得聊完具体配置最后说点架构层面的思考和个人经验。高可用架构不是一步到位的是随着业务增长逐步演进的。我经历过的典型路径是阶段一单机挂了就挂了。阶段二Keepalived双机热备解决单点。阶段三KeepalivedHAProxy解决单点七层调度。阶段四KeepalivedLVSHAProxy解决高并发。阶段五多机房、多活、容器化。大部分业务到阶段三就够了阶段四是给真正高并发的场景准备的。不要盲目追求复杂架构架构的复杂度要和团队的技术能力匹配。我见过太多团队上了LVS之后出问题没人会排查最后又退回HAProxy。几个我踩过的坑分享出来让大家少走弯路第一Keepalived的notify脚本一定要测试。我见过notify_master脚本写错导致切换后服务起不来比不切换还惨。脚本要幂等要能重复执行。第二LVS的DR模式RS的ARP抑制一定要配。这个坑我踩过三次每次都是VIP被RS抢走排查半天。记住那两个参数arp_ignore1arp_announce2。第三HAProxy的timeout不要照抄网上的。每个业务的请求特征不一样要压测后调。我一般先用默认值跑一周看日志里的timeout分布再针对性调整。第四健康检查的阈值要合理。rise和fall设太小容易抖动误判设太大故障发现慢。我的经验是inter 2srise 2fall 3这个组合在大部分场景下平衡得比较好。第五一定要做故障演练。配置写得再漂亮没演练过都是纸上谈兵。定期手动kill掉MASTER的Keepalived看VIP是否正常漂移手动停掉后端服务看HAProxy是否正确摘除。演练过的架构才是可靠的架构。最后分享一个我常用的Keepalived切换通知脚本切换时发消息到内部告警群方便第一时间知道#!/bin/bash # /etc/keepalived/notify.sh TYPE$1 NAME$2 STATE$3 VIP192.168.10.100 HOSTNAME$(hostname) MESSAGE[Keepalived] ${HOSTNAME} 状态变更为 ${STATE}, VIP: ${VIP} # 发送到内部告警接口 curl -s -X POST http://internal-alert.example.com/api/notify \ -H Content-Type: application/json \ -d {\message\: \${MESSAGE}\, \level\: \warning\} # 记录日志 echo $(date %Y-%m-%d %H:%M:%S) ${MESSAGE} /var/log/keepalived_notify.log这个脚本配合notify_master、notify_backup、notify_fault使用每次切换都有记录排查问题的时候特别有用。这套架构我用了很多年从几台机器的小项目到上百台的大集群都跑过核心思路没变过Keepalived管VIPLVS管四层HAProxy管七层各司其职不要越界。配置可以复杂但思路一定要简单清晰这样出问题的时候才能快速定位。 SEO 优化官网定制响应式建站教育培训建站