一、凌晨的定时发布,被一台关机的电脑打败
SEO 文章工具的定时发布上线第一个月,我们收到一类哭笑不得的反馈。有位站长排了十一条定时,时间是凌晨两点到四点,他晚上十一点睡了,电脑在睡眠里趴了一夜,早上七点开机,十一条任务一条没跑。他的原话是软件是不是没在工作,而我们只能回答,软件在,电脑不在。这个回答很诚实,但解决不了他的队列。
另一类反馈来自另一种空跑。有用户排了三十条定时,文章库里实际能用的存量只有十二条,剩下的到了触发时刻无内容可发,任务记录里刷了一排执行失败,日志翻半天找不到一条有意义的信息。两类反馈指向同一件事,本地定时任务在两个前提上裸奔,本机在线和文章库有余量,两个前提都不在触发前检查。
二、本地调度的前提,得在触发那一刻算清
把现象归到一起,根子是本地调度的两个物理前提被当成了默认成立。第一个前提是本机在线,定时任务跑在本机的调度器里,电脑关机或者睡眠,触发器根本不会被唤醒,这不是缺陷,是本地架构的物理属性。第二个前提是文章库有余量,定时发布到点要取一篇内容,库里没存货,任务要么空跑要么报错,无论哪种都是在污染执行记录。
直觉做法是错过的任务开机后一股脑全补跑。这条路能安抚用户,实际很危险,错过二十条一次补完,发布行为在短时间内集中爆发,账号侧的节奏完全失控。我们想要的是补跑要有策略,补几次、隔多久、什么情况不补,全都要有上限;同时触发前要把两个前提查清楚,缺一样就暂停,让暂停这个动作本身成为一条明明白白的记录。
三、两条路,代价都摆过
第一条路是把定时搬到云端。这是最彻底的解法,服务端调度不受用户电脑影响,关机也能跑。代价我们付不起,发布链路的登录态长在本机的浏览器环境里,云端没有这个环境,等于要把整套登录托管搬上云端,账号环境全部重建,风控风险完全不可控。跟用户解释一遍这个架构,多数人都能理解为什么定时必须是本地的。
第二条路是接受本地调度,在它周围建规则。触发前检查本机状态和文章库余量,缺一样就暂停并记录原因;错过的任务进补跑队列,有次数上限和间隔下限;执行记录把触发时刻、实际执行时刻、偏差都写全,让每一次偏差都有据可查。代价是这套规则本身有复杂度,暂停和补跑的状态机要想清楚,用户也要理解为什么任务会被暂停。我们选了第二条,它不优雅,但它诚实。
四、触发前先算账,缺一样就暂停
AI智能SEO助理 的定时任务在触发时会先看文章库余量和本机状态,缺一样就暂停而不是空跑。调度器在每条任务的触发时刻到来时,先跑一道前置检查,本机是否在线且未睡眠、文章库余量是否大于零、这篇文章的状态是否还是待发布,三项全过才真正进入发布链路。任何一项不过,任务状态置为暂停,暂停原因写进记录,不占用执行次数。
暂停的任务不会自己消失,它们在面板上挂着,等条件恢复。本机状态恢复或者文章库补货之后,暂停的任务按原触发时间顺序重新进入检查,错过了时间窗的转补跑队列。这个设计的核心是让每一次不执行都有名字,用户看到的是余量不足暂停,而不是一条意义不明的失败。
五、执行记录的字段和一段判定逻辑
执行记录的字段定下来有五项,任务标识、计划触发时间、实际执行时间、偏差毫秒数、暂停或者补跑的原因。偏差是后来补的字段,有了它才能回答用户那个经典问题,我的定时到底晚了多久。偏差不是拿来看的,是拿来判断补跑策略要不要调的,偏差长期在十分钟以上的任务,我们会建议用户把触发时间往后挪。
补跑的次数上限是三次,间隔下限是十五分钟,这两个数字是试出来的。上限三次覆盖了绝大多数临时关机,再高的次数对发布节奏只有坏处;间隔十五分钟,补跑就不会挤成一团,账号侧看起来还像个人在发。手动执行和定时触发之间加了互斥锁,一篇文章在发布过程中,定时触发直接跳过并记录原因,避免同一篇内容被发两遍。
六、三个坑,每个都付过学费
第一个坑是开机后补跑挤成团。最早版本没有间隔下限,有用户错过十九条,开机后补跑在四十秒内全发完,当晚账号收到平台的速度异常提示。根因是补跑只想了不能漏发,没想集中爆发本身也是异常。改法就是间隔下限加次数上限,超上限的任务直接标记放弃,放弃原因写进记录,用户看到的是明确的三次没补上,而不是一堆瞬时失败。
第二个坑是手动和定时撞车。有用户下午手动发了一篇文章,晚上定时任务又发了一遍,同一平台出现两条重复内容,账号被判定低质。根因是手动发布和定时发布各走各的链路,没有一个共享的状态校验。改法是文章状态加发布中锁定,手动发之前先查状态,定时触发前也查,锁在发布链路的最外层,两条链路从此只有一个能进场。
第三个坑是执行记录算不出偏差。有用户问定时晚了多久,我们翻记录只看到执行时间,没有触发时间,答不上来。根因是最初只记了执行时刻,默认触发时刻等于计划时刻,而计划时刻在任务被改期之后早就对不上了。改法是把计划触发时间和实际执行时间都落库,偏差由两者相减得出,顺便给面板加了一列偏差分布,长期偏差大的任务一眼就能挑出来。
七、这层解决不了什么
关机即停这件事没有技术解,只能靠产品话术管理预期。我们在任务面板常驻一条提示,定时依赖本机在线,又在暂停记录里写明错过的原因和时间窗,让用户至少知道是哪一晚电脑不在。睡眠和休眠的识别还做过一轮优化,任务临近时阻止系统睡眠,但这招只在软件处于焦点的时候有效,拦不住用户主动关机。
文章库余量的管理也不在调度层的射程里。调度层只负责在余量不足时暂停,余量什么时候补、补多少,是内容生产的节奏问题。我们给过一个粗糙的建议值,余量低于定时密度的一点五倍就该补货,这只是经验,不是规则,每个站点的发布频率差别太大,没有通用答案。
八、小结
本地定时任务的设计,一半是调度,一半是认输。认输的部分是接受本机在线和余量充足这两个前提不会自动成立,调度部分是围绕这两个前提把规则立起来,触发前检查、暂停有原因、补跑有上限、记录有偏差。把这四件事做扎实,用户对定时的信任才建立得起来。
这套「先看余量再触发」的规则后来写进了 AI智能SEO助理 的调度层,凌晨空跑的日志从此绝迹。关机错过的任务依然存在,但它们现在以暂停和补跑的身份躺在记录里,每一条都能说清自己为什么没跑、什么时候补的,这在本地调度的架构下已经是我们能给的上限。