任务状态显示成功,日志显示运行已完成,数据却是过期的或根本不存在。这种组合通常意味着定时任务在没有所需路径的情况下启动,而下游有某个环节把失败吞掉了。按点触发的时间表丝毫不能说明网络是否就绪。这两件事之间的空隙,正是这种故障藏身的地方。

准入属于这次运行,而不属于某个 cron 文件是否存在。

绿灯运行不等于任务完成

调度器只记录某个进程启动过、后来又退出;它根本不知道那个进程有没有到达它存在所要访问的资源。把失败的连接当作空结果、或者捕获错误后以零退出码结束的脚本,会永远显得健康。症状不是红色状态,而是一个看似合理、却挂在缺失工作上的状态。

在决定如何检查之前,先说明这次运行真正需要什么。备份可能需要私有 DNS 和经过认证的端点,而不仅仅是一个隧道进程。

检查连接,而不是接口名

一个名为 tun0 的接口可以在没有那个关键会话的情况下存在,另一个连接也可能占用这个名字。要检查任务所依赖的具体对象:一个配置文件身份、一个服务实例,或针对该资源的一次小型已批准操作。把检查限制在时间范围内,并让凭据远离进程参数和诊断日志。

也要定义断开连接时的结果。普通跳过、短窗口内重试、以及操作员可见的错过截止时间,是三种不同的答案,而重复的时间表并不会在它们之间做选择。

跳过和失败是不同的结果

[Service]
Type=oneshot
User=worker
ExecCondition=/usr/local/libexec/check-office-path
ExecStart=/usr/local/bin/private-task

在 systemd 部署中,ExecCondition= 会在工作负载之前运行那个检查器。它的退出行为很具体:零继续执行,一到 254 的代码会跳过剩余的启动命令而不把单元标记为失败,255 或异常终止则使其失败。这给出三种不同的信号,只有检查器的契约被有意映射到它们时才有用。重新定义成功的设置会改变局面,所以要记录这种映射。

记录跳过才让设计变得诚实。一次被跳过、却哪里都看不到的运行,与一次成功的运行无法区分;把检查器的每个错误都当成安静的跳过,会无限期地掩盖一个坏掉的部署。

保护整个运行,而不只是开头

就绪检查只观察启动之前的世界;它不会在此后监管每个套接字。当这条任务永远不能接受直连路径时,应附加一条持续执行的、经过批准的出站策略,覆盖 DNS、IPv6 以及隧道自身的传输。切换主机的全局 IPv6 状态,不能替代针对该任务的限定策略。

决定新事件是否可以与仍在运行的任务重叠,把这条规则交给工作负载负责人,并让重试对数据操作是安全的。断开时停止任务只能限制工作,并不能对回退流量作出任何保证。

用三种情况验收这套流程:路径就绪、路径不可用,以及运行中途丢失。比这更少的测试,检验的是时间表,而不是任务。

相关文章