做运维的都知道一句糙话:后端挂一台叫事故,入口挂一台叫灾难。后端挂了,负载还活着,摘掉故障节点接着跑;入口挂了,域名解析到哪儿都进不去,客户只看到转圈,你连"正在处理"这四个字都没机会显示。
所以但凡业务量上到一定规模,租服务器的第一步不是挑多强的 CPU,而是想清楚这个入口怎么做。四层负载这一层,很多人的第一反应是 Nginx stream 或者 HAProxy,能用,但真到了几万并发、小包密集的场景,用户态代理那个"每条连接都要建 socket、都要在内核和用户态之间倒腾一遍内存"的开销就开始咬人了。这也是为什么老一批运维到现在还在用 LVS —— 它把转发这件事丢回内核里做,快得不像话。
但快是有代价的。LVS 不是装个 ipvsadm 敲两条命令就能跑的东西,它有一堆硬门槛,而且这些门槛不是软件层面的,是你租机器之前就得跟机房确认的网络层面的事。我见过最多的情况不是配错参数,是机器买完了、系统装好了、规则也下发成功了,然后发现 Director 和 RealServer 压根不在同一个二层里 —— 这套架构从根上就不成立,前面所有工作白干。
这篇不打算写成教程,命令谁都能搜到。我要讲的是三件真正会咬人的事,以及它们倒推出来的硬件和网络选型要求。
要点一:DR 模式的三条硬门槛(同二层、VIP 绑 lo、压住 ARP),漏掉任何一条,症状都是"Director 看起来一切正常,业务就是不通"。
要点二:Keepalived 脑裂比宕机更难查。两台都以为自己是主,VIP 打架,连接随机失败,监控上却显示两台都活着。
要点三:ip_vs 的连接表和超时参数,才是长连接业务真正的容量上限,不是 CPU,也不是带宽。
要点四:DR 模式下 Director 的瓶颈是 PPS 和网卡中断,不是带宽。选型时盯着带宽谈,方向就错了。
要点五:TCP_CHECK 只能证明端口在监听,证明不了应用活着。关键业务必须上 HTTP_GET 看业务路径。
先说清楚它为什么快,不然后面那些别扭的限制你没法理解。
LVS 的核心是一个叫 IPVS(IP Virtual Server)的内核模块。它工作在 netfilter 的 INPUT 钩子上 —— 也就是说,一个包进网卡、过了 PREROUTING,内核正准备往本机上层协议栈送的时候,IPVS 半路把它截下来,查一遍自己的规则表,发现目标地址是某个 VIP 且匹配某个虚拟服务,就按调度算法挑一台 RealServer,改写一下,然后直接从 OUTPUT/POSTROUTING 方向丢出去。
关键点在于:这个过程里没有 socket,没有用户态进程,没有内存拷贝。包从进来到出去,一直在内核的内存里,改的是那几十个字节的头部。而用户态代理呢?每条连接都得有一个(或者两个)socket,监听、accept、read、write,数据要在内核缓冲区和用户缓冲区之间来回搬,连接数一上去,上下文切换和内存带宽就成了主角。
说白了,LVS 是个"查表改包头"的东西,Nginx/HAProxy 是"代理连接"的东西。前者离硬件近,后者离应用近。四层转发这种不需要看内容的活,交给离硬件近的那个干,天经地义。
既然没有 socket,那 LVS 怎么知道回来的包该给谁?答案是连接表 —— 内核里的 ip_vs_conn 结构。每进来一条新连接,IPVS 就在哈希表里插一条记录,记下客户端地址端口、VIP、选中的 RS 地址端口以及协议,后面双向的包都靠查这张表做改写。
这张表是 LVS 一切性能神话和一切容量问题的共同源头。它让转发变得极快,但它也占内存、有上限、靠超时回收。后面有一整节专门讲它。
ipvsadm 只是个用户态的管理工具,通过 socket 选项/Netlink 把虚拟服务、RS、调度算法这些规则下发到内核,真正的转发跟它没关系 —— 你把 ipvsadm 进程杀掉,规则还在,业务照跑。生产上一般用 Keepalived 来管这套规则:它一边跑 VRRP 做高可用,一边按配置文件往内核里同步 RS 列表、按健康检查动态摘除故障节点。
所以一个典型的组合是:LVS 负责转发,Keepalived 负责"谁在转发"和"转发给谁"。前者快,后者稳,两个是不同的问题。
LVS 有四种转发模式,选错了不是性能差一点的问题,是架构压根跑不起来。这张表先把结论摆出来,后面再逐条解释。
| 模式 | 转发方式 | 响应包是否过 Director | 是否要求同二层 | 性能与瓶颈 | 适合什么场景 |
|---|---|---|---|---|---|
| DR(Direct Routing) | 只改写目标 MAC 地址,IP 头不动 | 不过,RS 直接回给客户端 | 必须同二层(同一 VLAN/广播域) | 性能最好,Director 只看入方向包,瓶颈在 PPS 与连接表 | 同机房、同网段的大流量入口,下行远大于上行的业务 |
| NAT | 改写目标 IP(回程改源 IP),RS 网关指向 Director | 过,进出双向都要走 Director | 不要求,可跨网段跨 VLAN | Director 是带宽与连接数双重瓶颈,RS 可以是私网地址 | RS 分散在不同网段、不方便绑 VIP、规模较小或做内部服务入口 |
| TUN(IP 隧道) | 在原 IP 包外再封一层 IP 头(IPIP)发给 RS,RS 解封后处理 | 不过,RS 直接回给客户端 | 不要求,可跨三层 | 接近 DR,但多了封装解封装开销,还要留意 MTU 与分片 | RS 跨地域/跨机房部署,又想让响应包不走 Director |
| FullNAT | 同时改写源 IP 与目标 IP | 过,回程要回到 Director 做反向改写 | 不要求,可跨网段 | 转发能力强,RS 不需要任何特殊配置,但连接表开销更大 | RS 完全不可控、不方便改内核参数的规模化内网环境 |
表格看完,我的立场很明确:能用 DR 就用 DR。这不是因为它"高级",而是它把最贵的那部分带宽 —— 下行 —— 从 Director 身上彻底摘掉了。Web、下载、视频、API 这类业务,请求包小、响应包大,DR 模式下 Director 只处理小的那一半,压力直接降一个量级。
NAT 模式的价值在"省心":RS 上什么都不用配,VIP 不用绑,sysctl 不用改,只要把网关指向 Director 就行,而且能跨网段。代价是进出双向的流量都要在 Director 上过一遍,它的带宽和连接数直接决定整套系统的天花板。规模小的时候这不算事,规模大了就成了锁喉的那只手。
TUN 我一般只在 RS 跨机房时才考虑。它解决了 DR 的同二层限制,但换来的是 MTU 问题:多一层 IP 头,包变大,如果中间链路 MTU 是标准的 1500,很容易触发分片或者直接丢包,排查起来比重配一次二层还烦。
FullNAT 单独说一句:它不在主线内核里,需要额外的内核补丁或模块。除非你的 RS 完全不可控(比如别人的机器、不能改内核参数的托管环境),否则别为了它去折腾非标准内核 —— 一次内核升级就可能让你一夜回到解放前。
DR 模式的原理一句话:Director 收到目标地址是 VIP 的包,查表挑一台 RS,把目标 MAC 地址改成那台 RS 的 MAC,然后原封不动从二层丢出去。IP 头一个字节都没动,目标地址还是 VIP。
这个"只改 MAC"的动作,把三个前提死死钉住了。
改完 MAC 就得靠二层交换把帧送到 RS,中间不能过三层路由设备 —— 路由器看的是 IP,它一看目标地址是 VIP,而 VIP 又不在它的路由表里指向 RS,这包就废了。所以 DR 模式的硬性要求是:Director 与所有 RS 必须在同一个 VLAN / 同一个二层广播域内。
这条不是你能改的,是你在租机器之前就必须确认的。下单前直接问机房三个问题:这几台机器能不能划到同一个 VLAN?能不能拿到二层互通的内网?交换机有没有做端口隔离(很多机房默认开端口隔离,二层直接不通)?问清楚了再付钱,别等装完系统才发现。
DR 只改 MAC 不改 IP,所以包到了 RS 的网卡时,目标 IP 还是 VIP。RS 的内核只认一类包:目标地址是自己某个接口上配置的 IP,或者是广播/多播。VIP 不在任何接口上?那内核直接判定"这不是给我的",丢掉或者按路由转发出去,业务进程连包都见不到。
所以 RS 上必须把 VIP 配上,而且配在 lo(回环)上,掩码用 /32。为什么是 lo 而不是物理网卡?因为如果你把 VIP 配在 eth0 上,这台 RS 就会对外宣称"我拥有这个 IP",ARP 层面的麻烦立刻就来了 —— 这正是第三个门槛要解决的问题。配在 lo 上,IP 是本机可接受的,但不会主动对外宣告,配合后面的 ARP 参数,就能做到"收得下、不抢答"。
Director 和所有 RS 上都有 VIP(Director 在外网卡上,RS 在 lo 上)。这时候如果交换机或者网关来一次 ARP 请求"谁是 VIP?",按 Linux 默认行为,谁都可能回答,而且回答的是自己的 MAC。于是上游设备的 ARP 表就漂了 —— 这一刻指向 Director,下一刻指向某台 RS,流量随机乱窜。
表现非常折磨人:一部分请求正常,一部分超时;你重启一台 RS,另一批请求又不通了;ping VIP 时通时不通。日志里什么都查不出来,因为每一台机器的配置看起来都对。
压住 ARP 就是靠两个 sysctl:arp_ignore 和 arp_announce。下一节展开。
包到了 RS,内核收下了,还得往上层送。如果你的 Nginx 只监听了 RS 的物理网卡 IP(比如 listen 10.0.0.5:80),那目标是 VIP 的包到了传输层找不到监听 socket,一样被丢。要么让业务监听 0.0.0.0,要么显式监听 VIP。这条不算门槛,但它是"前面三条都做对了,业务还是不通"的常见收尾原因。
这两个参数很多人会背,但不一定真明白在拦什么。明白之后你就知道为什么必须是这两组值,而不是"差不多就行"。
arp_ignore 控制的是"收到 ARP 请求时,我要不要回答"。默认值 0 的意思是:只要我本机任何一个接口上有这个目标 IP,我就回答,而且回答的是收到请求的那块网卡的 MAC。
改成 1 之后,规则变成:只有当ARP 请求里问的那个目标 IP,正好配置在"收到这个请求的那个接口"上时,我才回答。
套到 DR 场景里:ARP 请求从 eth0 进来,问"谁是 VIP"。VIP 在 lo 上,不在 eth0 上,所以 RS 保持沉默。而 Director 的 VIP 就在 eth0 上,它会回答 —— 于是上游设备的 ARP 表里,VIP 稳定地指向 Director 的 MAC。这正是我们要的。
arp_announce 管的是另一头:这台机器主动发 ARP 请求(比如要解析网关 MAC)时,用哪个 IP 当源地址。默认值 0 允许用本机任意接口的 IP,包括 lo 上的 VIP。
问题就出在这:RS 主动发 ARP 时如果拿 VIP 当源,收到这个 ARP 的交换机/网关就会顺手更新自己的 ARP 表 —— "哦,VIP 在这块 MAC 上",于是又把流量引到了 RS。改 ARP 表是人家设备的自发行为,你管不着,唯一能做的是别给机会。arp_announce=2 强制使用与目标地址同子网的接口地址作为源,lo 上的 VIP 就不再被拿出去宣告了。
实际配置里有个细节最容易漏:sysctl 里 conf.all.* 和 conf.<接口>.* 是两套。生效逻辑取两者的较严值,只改一边很可能不生效或者重启后行为不一致。稳妥做法是 all、lo、以及对外物理接口(eth0 之类)都写上,或者至少保证 all 和 lo 都覆盖到。
顺便提醒:这些是运行时参数,重启会丢。要么写进 /etc/sysctl.conf(或 /etc/sysctl.d/ 下的独立文件)并执行生效,要么写进开机脚本里,别只在命令行敲一遍就以为完事了。
别信"我配了"三个字。在网关或者同网段的另一台机器上,连续抓几次 VIP 的 ARP 响应,看返回的 MAC 是不是稳定指向 Director;再手动触发一次 RS 的外网访问,看网关侧 ARP 表有没有被改写。这两个观察做完,ARP 这块才算落地。
LVS 的调度算法一堆:rr(轮询)、wrr(加权轮询)、lc(最少连接)、wlc(加权最少连接,多数版本的默认)、sed(最短期望延迟)、nq(永不排队)、lblc/lblcr(基于局部性的最少连接,多见于缓存场景),以及两个哈希类的 —— sh(源地址哈希)和 dh(目标地址哈希)。
前面几个没什么坑,挑哪个看业务特性:RS 配置一致用 rr 最省心,配置有差异用 wrr/wlc 按能力分配,连接时长差异大的用 lc/wlc 更均衡。
sh(Source Hashing)的逻辑是:按客户端源 IP 算哈希,同一个 IP 的请求永远落到同一台 RS。这等于白捡了一个会话保持 —— 不用改应用、不用加 cookie、不用引入 Redis 共享 session,对老系统特别友好。很多人在"登录老是掉"的投诉压力下,第一反应就是切 sh。
切完确实不掉了,然后新的麻烦开始。
哈希是把源 IP 映射到 RS 集合上的,RS 数量一变,映射关系整体重算。加一台机器、摘一台故障机、甚至只是权重调整,都会让相当比例的客户端被分到新的 RS 上 —— 他们的会话没了,又变成"登录掉了"。也就是说 sh 把平时的会话稳定性保住了,代价是每次扩容或故障切换都会丢一批会话。
规模越小这个比例越吓人:从 2 台扩到 3 台,重分布的比例会非常可观(以实测为准),你要是赶在业务高峰期扩容,投诉量会立刻教育你。
源地址哈希假设客户端 IP 是均匀分布的,现实里完全不是。企业出口、移动网络 NAT、运营商 CGNAT,一大片用户会共用少数几个出口 IP。这些 IP 算出来的哈希一样,于是流量全砸在同一台 RS 上,其他机器闲着。加权也救不了 —— 权重只影响分配比例,改不了"同一个源 IP 必须落到同一台"这个前提。
所以我的建议很直接:sh 只适合当作过渡方案。真正要会话保持,在应用层做——共享 session、JWT 无状态、或者把状态外置到独立的存储。实在改不动应用,也要接受 sh 的代价,并且把扩容操作放到低峰期、提前摘流量,别在线硬切。
dh(Destination Hashing)按目标地址哈希,典型用途是透明缓存或代理集群:同一个目标地址的请求固定落到同一台缓存机,提高命中率。它同样有重分布的毛病,只不过触发条件是目标地址集合变化。做四层业务入口基本用不上它,别因为看到"哈希"两个字就以为和 sh 是一回事。
前面说了连接表是 IPVS 的核心数据结构,现在说它怎么变成天花板的。
每一条经过 LVS 的连接,无论是 TCP 还是 UDP,都会在这张表里占一个条目:TCP 从 SYN 开始建,收到 FIN 或 RST 后进入清理流程(还要等一段 tcpfin 超时);UDP 没有明确的结束标志,纯粹靠超时回收。
WebSocket、数据库连接池、MQ 长连接、SSE 推送,这些连接一旦建立可能几小时甚至几天不断。它们不占 CPU(绝大多数时间在等着),但每一个都牢牢占着一个连接表条目。
于是真实的容量上限出现了:不是 CPU 跑满,不是带宽跑满,而是连接表先被占满。表是有上限的,受内存约束,条目占满之后新连接进不来,表现是"业务量没涨,新用户就是连不上",而监控上的 CPU 和带宽曲线一片平静 —— 这种故障最难定位。
做容量规划时,正确的算法是:预估峰值并发连接数 × 每条条目的开销,再加上冗余。具体每条占多少内存、你的内核版本下阈值在哪儿,得自己在目标机器上压一遍,别拿别人的数字直接套(以实测为准)。
ipvsadm 提供了三个超时值可以调:TCP 连接(established 状态)、TCP FIN 之后、UDP。设置方式是 ipvsadm --set 跟上三个值。TCP established 的默认值量级在 15 分钟(900 秒)左右,具体以你的发行版和内核版本为准。
这个默认值对长连接是保护,对短连接高频场景是负担。想象一个接口每秒几千个短连接,每个连接结束得快,但条目要等很久才被回收 —— 表里堆了大量"已经死透但还没过期"的僵尸条目,白白占位。这种情况下就该把 TCP 超时往下调。
反过来,如果你的业务是长连接为主,超时调太短会误杀:客户端还在用,连接条目被回收了,后续包查不到表,直接被丢或者转发错乱。所以没有"正确的值",只有"适合你业务的值",而且必须跟着业务形态走。
ipvsadm -Ln 看规则,加 --stats 看每个虚拟服务/每台 RS 的累计统计(连接数、包数、字节数),加 --rate 看速率,加 -c(或者 -Lnc)直接看当前连接表的内容。做 LVS 运维,这几个参数应该形成肌肉记忆。
故障排查时的顺序一般是:先 -Ln 确认规则和 RS 权重有没有被健康检查改掉;再 --stats 看流量分配是不是均衡(不均衡往往是调度算法或者哈希倾斜);最后 -c 看连接表有没有堆积、有没有大量处于非 ESTABLISHED 状态的残留条目。
LVS 解决了转发,但它自己是个单点 —— Director 那台机器挂了,VIP 就没了。所以要有 Keepalived:两台 Director 跑 VRRP,主节点持有 VIP 并对外发通告,备节点听着;一旦备节点在约定时间内收不到通告,就认为主挂了,自己把 VIP 抢过来。
VRRP 的细节记几个就够:通告默认发往组播地址 224.0.0.18,IP 协议号 112,virtual_router_id(VRID)标识一个虚拟路由器组,priority 决定谁优先,state 配 MASTER/BACKUP 只是初始值,真正谁当主看优先级和通告。
正常的切换是"主挂了,备顶上",VIP 只有一个持有者。脑裂是两台都认为自己是主,两台都把 VIP 配在自己网卡上,两台都在发免费 ARP 宣称"VIP 在我这儿"。
后果比宕机恶劣得多:上游设备的 ARP 表在两个 MAC 之间来回跳,一部分请求被送到 A,一部分被送到 B;而两台机器的连接表各自独立,客户端的包这次落到 A、下次落到 B,会话直接断;TCP 层面还会出现大量莫名其妙的重传和重置。用户侧的表现是"时好时坏、随机失败",而监控上两台机器都活着、进程都在、资源都正常。
为什么比宕机难查?因为宕机是"确定性的坏",脑裂是"不确定的坏"。所有单点检查都过,只有端到端的业务指标异常。
一,通告被防火墙挡了。iptables/nftables 上一条没写全的规则、云环境的安全组、机房上联的 ACL,都可能把协议 112 或者组播流量给丢掉。主节点一直在发,备节点一个都收不到,于是备节点理所当然地认为主死了。
二,上游交换机禁组播。这在托管和云环境里太常见了 —— 交换机出于安全或者配置策略,直接不转发组播。这时候组播通告等于没发,必须用 unicast_src_ip / unicast_peer 改成单播点对点。
三,心跳链路单线故障。两台 Director 之间只有一条互联链路,这条断了,但两台到业务网都还通。于是两边都活着、都能对外服务,只是互相看不见对方 —— 最典型的脑裂剧本。业务网和心跳网一定要分开,最好物理上走不同的网卡和不同的交换路径。
四,VRID 撞车。同一二层广播域内,两个不同的 Keepalived 集群如果配了相同的 virtual_router_id,它们的通告会互相干扰,优先级高的那个会不断把另一个顶掉,表现为 VIP 反复漂移。多集群共存的环境里,VRID 必须统一分配、登记在案,别让各团队的配置文件各写各的。
几个配置项要一起上:
nopreempt(非抢占):主节点恢复后不主动抢回 VIP,避免网络抖动时来回切。抢占模式下,一次几秒的通告抖动就可能触发切换,主恢复又切回来,VIP 每漂一次就丢一批连接。生产环境我一般都开非抢占,切换这个动作宁可让人来决策。
vrrp_sync_group:一台机器上如果有多个 VRRP 实例(比如多个 VIP、或者内外网各一组),用同步组把它们绑起来,要切一起切,避免出现"外网 VIP 切了、内网 VIP 没切"这种半吊子状态。
garp_master_delay:抢到主之后,延迟一点再发免费 ARP,并且可以配重复发送次数。目的是给上游交换机/网关足够时间刷新 MAC 表和 ARP 表,别让切换后的头几秒流量还往旧机器上送。
vrrp_script + track_script:这是最重要的一条。默认的 VRRP 只判断"进程在不在、通告收不收得到",判断不了"这台机器上的转发是不是还正常"。写个脚本去探测真实的服务状态(比如本地 ipvsadm 规则是否还在、关键 RS 是否可达、上行链路是否通),把脚本挂到 track_script 上,脚本失败就降优先级。这样切换的依据才是真正的健康状态,而不是"进程活着"。
这一节讲实操落点,按"先排查、再放行、最后考虑单播"的顺序来。
用 iptables 的话,INPUT 链上要允许协议号 112 的入站包,目标是 224.0.0.18(组播模式)或者本机地址(单播模式);用 nftables 就对应 ip protocol vrrp。注意别只放 INPUT 不管 OUTPUT,双向都要看。
云环境和托管环境还有第二道闸门:安全组/ACL。这层不在你的机器里,得去控制台或者找机房开。很多"配置全对但不生效"的案例,最后都栽在这一层。
排查手法很朴素:在备节点上抓包,看 112 协议的包有没有进来。抓得到说明网络通、问题在 Keepalived 配置;抓不到说明被挡了,往上游一层层查。
判断标准只有一个:你的两台机器之间能不能正常收到组播。抓包确认收不到,且确认不是本机防火墙的问题,那就是上层网络不支持 —— 改单播。
配置方式是给每个实例指定 unicast_src_ip(本机用于发单播的源地址)和 unicast_peer(对端地址)。改成单播之后,VRRP 通告变成两台之间点对点的 UDP 通信,不再依赖组播转发能力,兼容性大幅提升。
但单播有个副作用要记住:它只支持两个节点。三个及以上节点的 VRRP 组播组,改成单播后结构就变了,别硬套。
VRID 唯一性:同一个二层域内,每个 VRRP 组的 virtual_router_id 必须不同。这个数字没有全局协调机制,纯靠人管,建议写进配置登记表。
认证:auth_type PASS 配上 auth_pass,防止同二层内其他误配置的实例把你的组搅乱。它不是安全机制(明文),只是防误伤。
advert_int:通告间隔别设太小。间隔越短,网络抖动误判的概率越高;间隔越长,故障切换越慢。常规业务取个折中值,配合前面说过的非抢占,稳定性会好很多。备节点判定主失效的时间大致是若干个通告间隔再加一点偏移时间(skew time),具体倍数以版本和实际抓包为准。
Keepalived 对 RS 的健康检查有好几种:TCP_CHECK、HTTP_GET、SSL_GET、MISC_CHECK、SMTP_CHECK。选错检查方式,等于把故障检测交给了假象。
它做的是 TCP 三次握手(或者半连接探测),握手成功就判定健康。这意味着它回答的问题极其有限:这个端口有没有进程在监听、内核还能不能完成握手。
回答不了的问题才是致命的:应用线程池是不是打满了、数据库连接是不是耗尽了、依赖的 Redis 是不是超时了、是不是陷在某个慢查询里出不来、磁盘是不是写满了。这些情况下进程还在、端口还在监听、握手照样成功,但对用户来说这台机器已经死了。
我见过最典型的:一台 RS 上应用假死,TCP_CHECK 全绿,LVS 继续往它上面分流量,三分之一的用户请求超时。监控大屏一片祥和,投诉电话已经打爆了。
HTTP_GET 可以指定 URL 路径、期望的状态码,还能校验返回内容的摘要。健康检查应该打在一个"真检查"的路径上 —— 不是返回 200 的首页,而是那种会真的查一下数据库、查一下依赖服务、再返回健康状态的接口。
这里有个平衡要把握:检查太浅等于没检查,检查太深又会把健康检查本身变成压垮 RS 的最后一根稻草。合理的设计是业务侧提供一个轻量但真实的探活接口:只验证关键依赖的连通性,不做重活。
HTTPS 后端用 SSL_GET,非 HTTP 协议用 MISC_CHECK 写自定义脚本(脚本退出码决定健康与否),邮件服务用 SMTP_CHECK。工具是齐的,缺的是愿意多花半小时去配的人。
检查间隔、超时时间、失败重试次数这三个值要一起调。间隔太短、重试次数太少,一次网络抖动就把一台健康的 RS 摘掉了;摘掉之后流量全压到其他机器,可能引发连锁反应。
还要留意权重相关的行为:故障节点通常被置为零权重移出调度,恢复后要不要自动加回来、加回来是立刻全量还是逐步恢复,这些都要明确配置,别用默认值裸奔。
讲了这么多机制,落到"租什么机器"上其实就两个角色:Director 和 RS。这两个角色的要求完全不同,别一视同仁地买。
Director 的要求很特殊:CPU 压力极小(IPVS 在内核里做转发,不跑业务),但对内存、网卡和机器独立性要求高。内存要撑得住连接表,网卡要好、要支持多队列,机器必须是独占的 —— 你绝不希望邻居的一个突发流量把你的中断抢光。
一万网络这档裸金属,官网明示价 ¥3999 起(以官网实时价为准),双路 E5-2698v4 的核数对 Director 来说是绰绰有余,真正的价值在于它是物理独享:没有虚拟化层的开销和干扰,网卡中断和 PPS 的表现稳定可预期。两台这样的机器做主备,成本可控,结构清晰。
再加几条实际选型时会用到的:一万网络深耕 IDC 19 年(成立于 2007 年),深圳南山总部,自营机柜最快 1 分钟上架;7×24 中文工单平均 5 分钟响应;硬件故障 10 分钟自动迁移;免费提供系统盘快照(每日 3 份 / 30 秒回滚)、网站备案协助、5-20G DDoS 防护。对 Director 这种关键角色,出问题时"有人接、能快速处理"比省几百块钱重要得多。
另外,网络这块的选型要点别忘了问:BGP 多线 + CN2 GIA 回国,华南/华东/华北/中国香港/海外多节点可选;能不能拿到同一个 VLAN、二层是否互通、交换机有没有端口隔离 —— 这三个问题直接决定你能不能用 DR 模式,比配置参数重要十倍。
不是所有角色都需要裸金属。像健康检查脚本的旁路执行机、配置下发与跳板、监控采集、日志汇聚、以及测试环境里的小规模 Director,用云主机更划算,官网明示价 ¥25 起(以官网实时价为准)。
我的常见搭配是:生产环境的 Director 用裸金属主备,而灰度环境、压测环境、以及跨节点的监控与配置管理放在一万云上。这样既保住了核心入口的确定性,又不至于为一些边缘角色付物理机的钱。
如果业务里有 GPU 相关或者需要工程师协助部署深度学习栈的部分,一万网络还有工程师 1 对 1 部署 CUDA / cuDNN / TensorRT / PyTorch / TensorFlow 的服务,开机即用;涉及合规架构的需求,可提供合规咨询与协助。
把前面所有机制倒推成一份下单前能勾的清单。
网卡看 PPS,不看带宽。这是最容易被搞错的地方。DR 模式下 Director 只处理入方向的请求包,而请求包通常很小 —— 一个 TCP 握手、一个 HTTP 请求头,几十到几百字节。这意味着带宽可能只用了很小一部分,但每秒包数已经非常高了。网卡处理小包的能力(PPS)和中断处理效率才是天花板。
多队列 RSS 必须关注。如果所有中断都压在一个 CPU 核上,那个核会先跑满,而其他核闲着 —— 这是小包场景最常见的"机器看着不忙但性能上不去"。选网卡时看多队列支持,上线后用软中断分布工具观察各核负载是否均衡(以实测为准)。
内存按连接表估。前面说过,连接数 × 单条开销 + 冗余。长连接业务按峰值并发估,不要按平均值估。
双机是底线。一台 Director 谈不上高可用。两台 + Keepalived,业务网与心跳网分离,最好走不同网卡。
所谓单臂,就是 Director 只有一条链路接入网络,收和发都走它 —— DR 模式通常这么部署,因为响应包不走 Director,进出的量天然不对称。双臂是收和发走不同的链路或接口,常见于 NAT 模式:请求从外网进、转发到内网 RS,响应从内网回、再从外网出,双向流量都要过。
算带宽时口径完全不同:DR 模式下 Director 的带宽压力约等于入方向请求量,RS 的出方向带宽才是大头;NAT 模式下 Director 要扛住进出双向之和。同样是 1G 的入口能力,DR 能撑的业务下行量远大于 NAT(量级差异以实测为准)。这也是"能用 DR 就用 DR"的量化理由。
RS 的要求反而简单:同二层、能改 sysctl、能绑 VIP、业务监听 VIP 或 0.0.0.0。真正要确认的是机房给不给这些权限 —— 有些托管环境为了安全限制改内核参数,那就只能退到 FullNAT 或者改用用户态代理。
RS 的出方向带宽要按业务实际下行算,别按 Director 的口径套。DR 模式下所有响应流量都由 RS 直接发给客户端,RS 的上行带宽就是业务的真实出口。
同 VLAN / 二层互通、交换机端口隔离策略、组播是否放行、VIP 是否需要机房配合做 ARP 相关登记。这些问题在付钱之前问清楚,比装完系统再改架构便宜得多。
为什么坑:RS 上把 VIP 配到 eth0,这台机器就会用 VIP 应答 ARP,上游设备的 ARP 表立刻漂到 RS 上,流量绕过 Director 直接进 RS,而且是哪台 RS 最后应答就飘到哪台,完全随机。症状是"Director 上的统计数字几乎不动,但业务偶尔能通"。
怎么避:VIP 一律配在 lo 上,掩码 /32;物理网卡只保留 RS 自己的真实地址。上线前在网关侧连续观察 VIP 的 ARP 响应 MAC 是否稳定。
为什么坑:arp_ignore/arp_announce 在 conf.all 和 conf.<接口> 两级都有,只改 all 或只改 lo,在部分场景下不生效,或者重启网络服务后行为变了。更常见的是只在命令行改,重启机器后全部回到默认值,故障在半夜复现。
怎么避:all、lo、对外物理接口都写;写进 sysctl 配置文件持久化;把这两个参数纳入上线检查清单,并在发布脚本里加一次校验。
为什么坑:通告不通,备节点必然抢主,脑裂;VRID 撞车,两个集群互相顶,VIP 反复漂移。这两种的表现都是随机的连接失败,日志里看不出所以然。
怎么避:备节点抓包确认 112 协议包能收到;本机防火墙和安全组/ACL 双向放行;上层网络禁组播就改单播;VRID 统一登记分配;两台之间业务网与心跳网分离。
为什么坑:端口能握手 ≠ 应用能服务。线程池打满、依赖超时、慢查询堆积的情况,TCP_CHECK 全绿,流量继续往死节点上分,故障被放大。
怎么避:关键业务换 HTTP_GET,探一个真实检查依赖的业务路径;探测间隔与重试次数留够余量,别让抖动误摘节点;配合 vrrp_script 做 Director 侧的整链路健康判断。
为什么坑:长连接业务长期占表,短连接高频业务堆积僵尸条目,两种都会让表先于 CPU 和带宽见顶。表满之后新连接进不来,而监控上看不出资源异常,排查方向极易跑偏。
怎么避:按峰值并发估内存;用 ipvsadm -Lnc / --stats 定期看表的情况;按业务形态调 ipvsadm --set 的三个超时值,长连接业务别往短了调,短连接高频业务别用默认的长时间;具体数值以实测为准。
基本没有干净的办法。DR 靠改写 MAC 转发,帧必须在二层送达,中间过一次路由就失效了。真要跨网段,就换模式:TUN 用 IP 隧道可以跨三层,代价是封装开销和 MTU 问题;NAT 也能跨网段,代价是进出流量都走 Director。别指望靠静态路由或者策略路由"救"DR,那是硬限制,不是配置问题。所以这条一定在租机器之前跟机房确认,能拿同 VLAN 就选 DR,拿不到就老实换方案。
按顺序排查四条:一,VIP 是不是绑在 RS 的 lo 上、掩码是不是 /32;二,arp_ignore/arp_announce 是不是都改了并且持久化了;三,RS 上的业务进程是不是监听在 VIP 或 0.0.0.0 上,只监听物理网卡 IP 的话包到了也会被丢;四,ipvsadm -Ln 里 RS 的权重是不是被健康检查置零了。这四条占了"看起来都通但业务不通"的绝大多数,逐条核对比抓包更快。
两台 Director 上分别执行 ip addr,看 VIP 是不是同时在两台机器上;再看系统日志里有没有同时出现进入 MASTER 状态的记录;然后在网关侧看 VIP 对应的 MAC 是不是在跳。三者有两者命中,基本就是脑裂。应急处理是先确定性保留一台(停掉另一台的 Keepalived 或者把它下线),让 VIP 唯一,再回头查通告为什么不通 —— 别在脑裂状态下慢慢排查,那期间业务一直在丢。
老实说,少丢有限,只能减轻。可行的做法:一,扩容放在业务低峰;二,先把要操作的 RS 权重调低、等存量连接自然结束,再动配置;三,如果业务允许,给会话设置一个不算太长的过期时间,让用户重新登录的成本可控。但这些都是缓解,根治还是把状态外置 —— 共享 session、无状态令牌、或者把状态放到独立存储里,之后调度算法就能回到 wlc,扩容随心意。
看业务形态。长连接为主(WebSocket、连接池、消息推送)时,TCP 超时不能调太短,否则客户端还在用就被回收,后续包查不到表直接丢弃;默认值量级是 15 分钟,多数长连接场景够用。短连接高频时反过来,默认值太长会堆积已失效的条目,可以适当往下调,配合观察连接表的实际占用。UDP 因为没有连接终结标志,完全靠超时回收,按业务包频率定。所有调整都要跟着 -Lnc 的观察走,以实测为准。
别按带宽选。DR 模式 Director 只处理入方向的请求包,包小、量大,真正的瓶颈是每秒包数(PPS)和网卡中断的处理效率。所以优先级是:网卡(主流服务器网卡、支持多队列 RSS)> 内存(按峰值并发连接数估连接表开销)> CPU(够用就行,IPVS 转发本身不吃 CPU)。另外必须是独享物理机,虚拟化环境下邻居的突发流量会干扰中断处理,这点对 Director 是致命的。上限在哪儿,压一遍才知道,别直接套别人的数字。
没有标准答案,得权衡"发现故障的速度"和"误摘节点的风险"。间隔太短、重试太少,一次网络抖动就把健康节点摘掉,流量压到其余节点可能引发连锁;间隔太长,故障节点要拖很久才被移除。经验做法是间隔取一个中等值,配合连续失败若干次才判定失效,超时时间留出正常响应时间的余量。判定恢复时建议连续成功若干次再加回,避免节点在健康与不健康之间反复横跳。
这篇的观点我摊开讲清楚:四层入口这一层,LVS + Keepalived 依然是性价比最高的方案,因为转发在内核里做,快得扎实,而且不吃 CPU。但在租来的服务器上落地它,成败不在软件配置,在你下单之前问没问清楚那个二层。
同 VLAN、VIP 绑 lo、ARP 压住 —— 这三条缺一条就是"Director 一切正常、业务死活不通",而这类故障的排查成本远高于前期确认的成本。所以我的建议顺序是:先确认机房能不能给你二层互通、交换机有没有端口隔离、VIP 要不要登记;确认完再选 DR;拿不到二层就别硬撑,退到 TUN 或 NAT,或者干脆用用户态代理,把架构的复杂度换成可运维性,这笔账是划算的。
剩下两件事同样别省:Keepalived 的健康判断一定要做到应用层(vrrp_script + HTTP_GET),别让"进程在"骗过你;连接表和超时参数要按业务形态调,长连接业务的容量天花板在那里,不在 CPU 也不在带宽。这三块都落地了,这套入口才算真的稳。
本文所述 LVS/IPVS 转发机制、四种模式差异、arp_ignore/arp_announce 行为、ip_vs 连接表与超时参数、Keepalived VRRP 通告机制与健康检查方式,均属于相关开源组件的公开机制说明,具体表现随内核版本、发行版与实际网络环境而异,文中涉及定量的说法请以实测为准。
文中涉及的一万网络产品与报价:裸金属 E5-2698v4×2 ¥3999 起、一万云 ¥25 起,均为官网明示档位,以官网实时价为准;其他任何推算或行业参考价均标注为「(预估)」「以咨询为准」,不作为成交价。品牌信息:一万网络深耕 IDC 19 年(成立于 2007 年),深圳南山总部,具备增值电信业务经营许可证、国家高新技术企业、专精特新等资质;提供 7×24 中文工单(平均 5 分钟响应)、硬件故障 10 分钟自动迁移、免费系统盘快照与网站备案协助、5-20G DDoS 防护、BGP 多线 + CN2 GIA 回国、华南/华东/华北/中国香港/海外多节点等能力。
更多产品与资质信息请见官网 https://www.idc10000.net/。具体以签约时最新报价与合同为准。
Copyright © 2013-2020 idc10000.net. All Rights Reserved. 一万网络 科技有限公司 版权所有 深圳市科技有限公司 粤ICP备07026347号
本网站的域名注册业务代理北京新网数码信息技术有限公司的产品