你接手了一个每天 04:10 重启 OpenVPN 的 cron 任务,它让系统稳定了一年。但它也会在固定时刻切断一条健康的隧道,而对真正发生在午餐时间的故障无动于衷。按日历重启是维护决策。恢复是另一套设计,需要具体的触发条件。

三种故障形态需要三个不同的负责人。先选故障,机制自然会跟上。

三种故障,三个负责人

对端已经消失时,隧道仍可能处于启动状态:进程在跑、接口存在,但没有任何有用的流量通过。对端正常时进程也可能已死,这时只有当初启动它的东西才能把它带回来。隧道后方的应用可能在隧道和对端都健康时坏掉,此时重启客户端只会扩大故障,却碰不到根因。把这三种情况分开,就是整个决策。

每一种都有自己的信号和负责人。存活状态归 VPN 协议管,进程生命周期归服务管理器管,应用健康归权限很窄的监控管。

存活类选项能做什么、不能做什么

keepalive 是一个辅助选项,会展开成 ping 与 ping-restart 这一对,正如链路选项参考所描述,而它产生的超时在服务器和客户端上并不相同。服务器下发的值还可能覆盖客户端本地的配置,所以本地文件里看起来正确的超时,未必是实际生效的那个。

这使它成为处理对端失联的正确工具,却是处理进程死亡的错误工具,因为已退出的进程无法运行自己的定时器。它对隧道后方的应用是否有响应也一无所知,因为这种交换发生在两个 VPN 端点之间。不做角色、预期中断和重新认证行为这三项核对,就把另一套部署的超时对直接抄过来,正是稳定隧道开始抖动的起点。

服务管理器负责什么

如果守护进程退出,启动它的管理器决定接下来发生什么。以失败为依据、带延迟和启动速率上限的重启策略,能处理崩溃循环,而不会把它变成 fork 炸弹。这些设置只对进程结果和超时作出反应,无法发现进程还活着却毫无用处。这不是要用更宽的策略去填补的空缺,而是生命周期与存活之间的边界。

归属和设置同样重要。桌面网络管理器启动的连接,应当保留该管理器的恢复安排;为同一个接口再加一个竞争的服务单元,就等于让一条隧道有了两个主人。选一个,并写清楚是哪一个。

什么时候定时重启是合理的

定时重启可以是一次合理的维护动作:它有负责人、有时间窗口、有具名实例,也有独立的进入方式。它不能成为一项通用可靠性策略,还在固定时刻切断所有人。

如果重启是为了绕过已知的泄漏或卡死状态,请在单元描述里写清楚,否则下一个人会永远把它留着。

测试真正重要的情形:进程还在而对端消失、进程退出、重试需要新的凭据、隧道恢复而应用仍然损坏。观察哪个组件作出反应,以及它留下了什么状态。

正确的问题不是多久重启一次,而是应该由谁先发现故障。

相关文章