摘要
- RFC 2391 让一个虚拟服务器地址代表一个后端池;LSNAT 为每条新会话选择成员,并以绑定状态约束后续所有数据包。
- 轮询、会话数、流量、权重、路由代价与探活都只是选择依据,不能证明应用真实容量,更不能证明请求一定成功。
- 把死机从新分配名单中移除,只保护未来会话;已经绑定的会话不能中途换机,避错、连续性与故障接管是三张不同凭证。
地址没有告诉客户端:谁在接单
服务器扩容最容易被讲成一道除法题:一台机器扛不住,就增加几台,把请求平均分开。真正困难的不是池里有几台机器,而是客户端仍然只认识一个服务入口,同时每一条持续中的对话必须找到同一个执行者。
RFC 2391 把 RFC 1631 的网络地址翻译,与“实时”负载分配算法组合在一起。客户端继续访问虚拟服务器地址。LSNAT 在中间看到新会话,从池里挑出一台机器,改写数据包并转发。池成员可以添加、替换或下线,客户端无需随之修改。
这种透明性没有消灭决定,只是把决定挪走了。虚拟地址不再等于某台物理服务器的身份,它指向一个选择面。谁有资格进入池、哪些服务参与分配、采用哪项指标、哪个成员被选中,都发生在客户端看不到的本地控制面上。
这与 RFC 1546 的任播历史不一样。任播关注同一个服务地址如何经由路由抵达不同实例,以及逐数据报选择会怎样破坏稳定身份。RFC 2391 的特征是一个记住选择的翻译器。它不是每次问“这个包去哪”,而是在第一次选择之后问“这条会话已经归谁,后续包怎样继续服从这个记录”。
第一次选择为什么会变成约束
RFC 2391 把翻译过程分为三段。第一段是会话绑定:新会话与池中某台主机的地址建立关联,这项关联给后续所有数据报设定翻译参数。第二段是查找与翻译:属于同一连接的包先查会话表,再改写相关字段。第三段是解绑:系统判断会话已经结束,服务器不再对它负责。
“绑定”不是一个推荐结果,而是一段有权力的状态。去程数据包的目的地址、必要时还有目的端口,被改成后端的值;回程包的源地址和端口被改回客户端认识的虚拟服务。IP、TCP、UDP 或 ICMP 校验字段也要随之调整。
因此,请求与响应必须穿过同一个 LSNAT。若回程绕开翻译器,客户端会看到不匹配的身份。若故障后流量被送到另一台没有会话表的翻译器,它只知道虚拟地址,不知道当初选了哪台后端,也不知道端口怎样对应。
RFC 2391 对此没有模糊处理:会话一旦分配给某台主机,在结束以前不能移到另一台。分配算法只决定新会话的归属,不负责搬运传输层状态、应用上下文或已经做到一半的工作。
“负载”其实有许多互不相同的替身
最简单的轮询不观察负载。它只保证选择次序均匀,暗中假设每条会话成本相近、每台服务器能力相近。一次昂贵查询和一次廉价读取,在轮询表里都是“一个”。
“最少会话优先”多看了一层:谁当前绑定的会话少,下一条就交给谁。它仍然把长时间空闲连接与高速传输算成同一种单位,也把不同硬件当成同等资源。
按数据包或字节计数,可以观察到翻译器真正经过的流量,却仍然只是在近似系统负载。一个很小的请求可能触发昂贵计算;大块顺序传输反而可能只消耗少量 CPU。可见的数据面指标与后端内部压力并不是同一事实。
权重把运维判断写进公式。FTP 会话可以比 Telnet 会话权重高,一台更强的服务器可以获得更高能力系数。这让假设变得可调、可审计,却没有让它变成实时测量。数字越精细,也可能只是更精细地表达旧经验。
RFC 2391 直言,想精确知道远端主机当下有多少未使用容量并不容易。后端可以主动向选择器报告资源,但这又引入报告周期、延迟、真实性和过期问题。状态一旦跨越网络,就已经可能落后于下一次选择。
这些算法真正能回答的是:“在当前模型和当前证据下,下一条会话交给谁?”它们不能回答“谁拥有客观最多的容量”,也不能替某个用户保证结果。
路由代价只说明选择器所见的路径
当服务器分布在不同位置,RFC 2391 允许选择器读取 RIP、OSPF 等路由信息,用到达代价参与决策。算法可以把路径代价与已分配会话数或流量结合。网络故障令某台服务器不可达时,它的代价可设为无穷大,从而不再接收新会话。
这项信号有明确边界。路由表说明控制面是否知道一条路径以及如何评价它,并没有预留带宽、CPU、内存或应用队列。路径存在,也不等于服务进程健康;路径短,也不等于请求会完成。
这正好与 RFC 2386 的资源地图文章划开边界。那篇讨论地图为何不是准入、预留或交付;RFC 2391 在地图或负载指标之后又多了一步——它把局部判断写成会话绑定。两者都提醒我们:描述某种可能性,并不会自动生成下一层现实。
完整证据链应当是:虚拟地址、池成员配置、负载或路径信号、选择策略、会话绑定、双向翻译、服务器响应、应用结果。少掉其中任何一环,绿色状态都可能只是提前颁发的结论。
宣布“死机”能改变未来,不能改写过去
若选择器继续向不响应的服务器分配新会话,负载均衡就会变成黑洞制造器。RFC 2391 因而提出启发式探活:定期发送 ping,或者在刚分配新会话后观察该成员是否发回数据报。数秒内没有响应,可以宣布它死亡,并停止向它分配新会话。
重新纳入也依赖试探。等待几分钟后,系统可以周期性地再次分配新会话,观察响应时间。所谓“存活”不是永久登记,而是某项本地策略依据有限信号得出的暂时结论。
ping 通只证明某一层能回声,不证明应用及其数据库、磁盘或证书链可用。新会话无响应也未必准确指出故障位于主机、网络、服务还是请求本身。选择器必须在原因尚未完全闭合时采取行动。
这里有一个必须标明为推论、但由原文两条事实共同支持的结论。探活章节说的是停止分配“新会话”;前文又说已分配会话在结束前不能迁移。因此,死机抑制可以减少下一次错误选择,却不能把现有会话接到健康后端。
“池整体仍然可用”和“这位用户的会话仍然连续”会同时一真一假。三台健康服务器可以继续接单,第四台留下的所有绑定却仍然失败。用池级可用率覆盖会话级损失,会把恰恰需要观察的对象抹掉。
RFC 3022 后来把同一问题延伸到 NAT 自身:故障后把包改道到另一台 NAT,可能在切换时令流失败;除非设备共享配置与会话状态,新的路径并不能还原旧对话。RFC 3234 进一步区分故障接管与重启:硬状态若没有副本,替代机器只能让用户重新开始。
系统也不总知道会话何时真正结束
绑定不能永久保留,所以 LSNAT 还要决定何时解绑。TCP 的 FIN、RST 提供明显线索,但对端重启、包丢失或异常消失,可能让翻译器收不到终止信号。UDP 没有统一的“会话结束”消息。应用认为的一段业务,也未必与 NAT 看到的五元组生命周期相同。
空闲超时于是承担了判断。时间太短,会删除仍在等待下一次数据的合法绑定;时间太长,会积累已经死亡的状态并占用表项与端口。RFC 2663 后来明确指出:一般情况下无法区分长时间空闲与已经消失的连接,NAT 的会话观也不保证等于应用的会话观。
RFC 4787 又为 UDP 映射给出最低超时与刷新要求,同时记录不同实现间的巨大差异。这类规则改善兼容性,但仍不能把沉默变成确定知识。
解绑不是后台清理小事。它决定旧身份何时停止有效、迟到的数据包是否还能找到责任人,以及有限资源何时可以复用。会话的诞生与死亡,都由中间点在不完整证据上作出本地判断。
LS-NAPT 用更多状态换取更少拓扑束缚
基础方案把后端池放在一个所有往返都自然经过 LSNAT 的边界内。RFC 2391 还描述了 LS-NAPT:通过同时改写两侧字段,迫使客户端与服务器都把数据包送回翻译器。这样,后端不必局限在同一个存根域,接入链路也更容易扩展。
代价同样写在规范里。需要更多翻译,处理更复杂;该配置只面向 TCP 与 UDP;可用客户端端口限制同时会话规模。物理拓扑限制被放宽,依赖却转移到端口空间、状态表和中间点性能。
这延续了 NAT 的根本交换。RFC 1631 认为无需修改主机即可增量部署是巨大优势,同时承认 IP 地址的端到端意义被拿走,网络内部必须增加状态。LSNAT 利用这种可塑性,把服务器选择也塞进了地址背后。
RFC 7098 后来把“持久性”定义为让一条客户端会话在同一台服务器上完成,并描述有状态负载均衡器保存“流标识—服务器”关联。这个词能准确解释 RFC 2391,却也容易被误读:持久性意味着不换,并不意味着随时能换。
一张虚拟地址,八层不同现实
虚拟地址只证明入口。池配置只证明候选名单。测量只证明选择器看见了某种信号。算法只证明按某条规则做了选择。绑定证明某条会话归属某成员。翻译证明数据包按该记录通过。服务器响应证明部分运行行为。应用结果才证明用户要的工作是否完成。
每层都有自己的控制者。运维者管理池和策略;选择器解释指标;LSNAT 保存权威绑定;后端掌握实际资源和应用状态;端点观察最终效果。任何一层越权替后面几层签字,都会制造虚假确定性。
Heng Lu 的笔记反复强调现实层级:初始规范应尽量小,未来决定留在本地,记录描述现实而不创造现实,最终由运行代码与观察结果交付证据。RFC 2391 正好展示了这一纪律。它让客户端界面变得简单,却没有否认简单界面背后的选择、状态、路径与不确定性。
池里确实还有空闲机器。问题是那条会话已经不是“下一条”。一旦选择写进状态,剩余容量便不再是一份故障接管方案。
来源
- RFC 2391 — Load Sharing using IP Network Address Translation
- RFC Editor:RFC 2391 记录
- IETF Datatracker:RFC 2391 历史
- RFC Editor:RFC 2391 勘误检索
- RFC 1631 — The IP Network Address Translator
- RFC 1794 — DNS Support for Load Balancing
- RFC 2663 — IP Network Address Translator Terminology and Considerations
- RFC 3022 — Traditional IP Network Address Translator
- RFC 3234 — Middleboxes: Taxonomy and Issues
- RFC 4787 — Network Address Translation Behavioral Requirements for Unicast UDP
- RFC 5382 — NAT Behavioral Requirements for TCP
- RFC 7098 — Using the IPv6 Flow Label for Load Balancing in Server Farms
- Heng Lu — Running-Code Primacy
- Heng Lu — Minimum Initial Specification, Localized Future Decision, and Voluntary Adoption
- Heng Lu — Reality Layers, Symbolic Power, and Clarity
会员简报
档案背景详情
使用相应会员等级登录,即可解锁完整简报与来源注释。
仅限 Strategic Circle
Strategic Circle
所有读者均可浏览。加入并登录后可解锁档案简报。
加入 Strategic Circle仅限 Leadership Alliance
Leadership Alliance
符合条件的 IP 资产所有者和管理层可登录查看 Leadership Alliance 简报。
加入 Leadership Alliance
