一个带两百条路由的配置在一台机器上能用,在另一台只装进去四十条。引擎、启动它的集成层,以及向它下发配置的服务器,三方都有发言权,也都可能在各自不同的位置截断列表。把故障当成单一上限来读,就会翻错文件。机制分为三段,停下的那一段会留下可见痕迹,只要知道该找什么。

三个阶段,三种不同的上限

首先,引擎解析这一选项,并判断当前版本是否认识它。接着,集成层安装引擎所报告的内容,它自己的代码也可能压缩或改写列表。最后,服务器在任何客户端阶段看到东西之前,就决定向某个身份下发多少条路由。三个阶段,三道上限,其中只有一个是配置文件里的数字。

抬高一道上限,对另外两道毫无作用。一条被拒绝的下发路由,可能是服务器上的策略决定,可能是客户端解决的重复,也可能是安装方丢弃多余条目的限制。这些情况的修法各不相同。

先分开这三者,再开始测量。解析错误的报文会点名某个 token,安装方的上限会留下一张偏短的路由表,而策略决定什么都不留。痕迹会告诉你先查哪一段。

StageWho decidesWhat you can see
ParseClient engineAn error naming the option
InstallActivation ownerA route count below the pushed count
OfferServer policyA route absent from the pushed list

先开口的是解析器

未知选项会响亮而提早地失败,错误文本会点名那个 token。这是最容易辨认的一段:把原文报文与已安装的引擎版本对照,因为某个版本新增的选项在上一版里就是未知的。从更新的部署里复制来的配置,正是这种不一致的常见来源。解析器绝不会悄悄忽略它不认识的指令。

被接受的选项并不能说明结果。解析通过了,列表仍可能被安装方裁掉,或者服务器根本没有下发过。把干净的解析当作继续排查的许可,而不是证据。

版本字符串要记真正运行过的那份二进制,而不是包管理器以为装了的那份。这两者不一致的次数比想象中多。

安装方也有自己的上限

掌握激活的组件可能是 NetworkManager 插件,而不是引擎二进制。它可能在隧道出现之前就施加自己的限制。它的编辑器可能显示一个运行中的引擎从不读取的字段,也可能去读编辑器不显示的字段。两种情形从外面看都像客户端缺陷,而改配置都解决不了。

要数实际落地的,而不是配置里写的。ip route show dev tun0 命令会列出已安装的路由,把它与下发列表对比,就能把被丢弃的路由与从未发送的路由分开。数字若与下发一致,怀疑就该回到服务器。

为了让数字变大而在引擎二进制外面套一层 shell,会模糊升级过程,也让回滚变成猜测。它还会把真实上限藏起来,让下一位读配置的人看不到。

下发给你什么,由服务器决定

按客户端的策略会在传输之前缩小列表。某个客户端专属文件可能为某个身份加上路由,组策略也可能把它们去掉,而客户端无法区分被过滤的路由和从未定义的路由。正是这种模糊,让服务器侧的记录变得重要。要索取该身份的实际下发列表,而不是模板。

把服务器记录与收到的列表对比。两者之间的差额就是策略层,通常比配置所暗示的更小。

在设计允许时,合并相邻网段,删除过期条目。更少、更大的路由,比更高的上限能解决更多情况。

在正确的地方改数字

使用真正掌握上限的那个组件的文档化设置。如果插件里没有这个字段,先确认插件是否早于该功能,或者路由是否归另一层后端管。然后在所选数值旁边记下引擎、插件与服务器的版本。下一次升级会重新打开这个问题,而正是这条记录让它可回答。

三方中任何一方升级之后都要重测。在正确位置抬高的上限,仍会随执行它的组件变化而移动。版本记录是唯一能让这种移动可预测的东西。

相关文章