webman定时任务实战_php webman内置crontab用法全解【功能】

workerman/crontab 不是系统 cron 的 PHP 封装,也不是“可视化后台”,它就是一个运行在 Worker 进程内的、支持秒级精度的纯 PHP 调度器。想让它稳定干活,得按它的机制来,而不是套用传统运维经验。

为什么任务写了却没执行?三处必查

90% 的“没跑”问题都卡在这三个地方,不是框架坏了,是启动/配置/表达式没对上:

php start.php reload 没执行 —— 改了 app/process/Task.php 后只改代码不 reload,旧进程还在跑老逻辑;restart 会杀进程,导致任务中断,必须用 reloadCron 表达式少写一位 —— * * * * * 是 5 位,会被 workerman/crontab 当成「每小时执行一次」;秒级任务必须写满 6 位,比如 */10 * * * * *(每 10 秒)回调里抛出未捕获异常 —— 比如 PDOException 或 RedisException,整个 Crontab 实例会静默退出,且默认不打日志;必须手动包 try/catch 并写入文件或 syslog

多个任务共存时为啥互相卡住?

所有 new Crontab() 默认注册在同一个 Worker 进程的事件循环里。一个任务 sleep(30) 或执行慢 SQL,整个循环就卡死,后面所有定时器全排队。

表现是:日志里任务 B 应该每 10 秒执行,实际间隔变成 42 秒、78 秒…top 看到单个 php 进程 CPU 长期 100%HTTP 请求也开始变慢甚至超时 —— 因为 Worker 进程被占用了解决方法不是加 try/catch,而是拆进程:config/process.php 里配两个独立进程,比如 ‘task_alarm’ => [‘handler’ => app\process\AlarmTask::class] 和 ‘task_report’ => [‘handler’ => app\process\ReportTask::class],把高敏感任务和耗时任务彻底隔离

秒级任务能写 * * * * * * 吗?

能,但非常危险 —— 它真会每秒执行一次,且每个 tick 都走完整解析+回调调用流程。高频触发下极易打满 CPU,尤其当回调里有 I/O 或未做限流时。

立即学习“PHP免费学习笔记(深入)”;

测试环境可以临时用,线上严禁无条件使用如果真需要高频触发(比如每秒检查 Redis 键是否存在),优先考虑 Timer::tick() + 协程驱动(Swoole/Swow),而非 Crontab务必加执行时间兜底:set_time_limit(3) 放在回调开头,防止单次执行失控注意:6 位表达式不支持 @reboot、@daily 等符号别名,只认标准字段格式

热更新配置到底能不能做到?

原生 workerman/crontab 不支持运行时增删改查,onWorkerStart 里 new 出来的实例生命周期绑定进程,reload 只是重建,不是热重载。

所谓“动态管理”,本质是绕开原生机制:把任务规则存进数据库,另起一个 CLI 脚本每 5 秒轮询,匹配 next_run_at 后调用对应逻辑或者改成发消息到 Redis 队列,由独立消费者进程执行 —— 这样 Webman 进程只负责触发,不承担执行Webman 自身不提供任务状态监控、失败重试、分布式锁;这些能力必须自己补,或接入 XXL-JOB、DolphinScheduler 等外部调度平台

真正难的不是写第一个 new Crontab(),而是理解它和进程、事件循环、错误传播之间的耦合关系。很多“失效”背后,其实是把调度器当成了黑盒,而没意识到它就在你当前的 Worker 进程里,和你的 HTTP 请求共享同一套资源。

声明:本站所有文章,如无特殊说明或标注,均为本站原创发布。任何个人或组织,在未征得本站同意时,禁止复制、盗用、采集、发布本站内容到任何网站、书籍等各类媒体平台。如若本站内容侵犯了原著者的合法权益,可联系我们进行处理。