Crontab在Webman中必须通过自定义进程并在onWorkerStart中实例化才能生效,config/process.php需正确定义handler类路径与命名空间,秒级调度须用6位Cron表达式,修改后必须重启进程。

Crontab 在 Webman 里不是“开个开关就能用”的功能,它必须靠自定义进程 + 正确注册才能跑起来。没配进程、没在 onWorkerStart 里实例化,任务压根不会触发。
config/process.php 必须声明进程类,路径错一个字母就失效
Webman 不会自动扫描 app/process/ 下的文件,你写了 app\process\Task::class,但 config/process.php 里没加对应条目,这个进程根本不会启动。
- 检查配置项 key 名是否与进程类名一致(比如
'task' => [...]对应Task.php) - 确认
handler值是完整命名空间类名,且大小写完全匹配(PHP 对大小写敏感) -
count字段默认为1,设成0或负数会导致进程被跳过,无报错、无声无息
new Crontab() 只能在 onWorkerStart 里调用
定时器必须绑定到 Worker 进程的事件循环上,而事件循环只在 onWorkerStart 触发后才就绪。放错位置等于白写。
Webman 2.2.0版本强化了 TCP/UDP 服务支持,优化路由组管理,并增强异步任务处理能力。结合协程与连接池技术,Webman 能轻松应对高并发场景,适用于网站、接口服务、即时通讯、物联网及游戏开发,兼具高性能、灵活扩展与稳定可靠,是多场景 PHP 服务开发的理想选择。
- 不能写在类属性初始化:
protected $crontab = new Crontab(...);→ 类未实例化就执行,直接报错或忽略 - 不能写在
__construct():此时 Worker 尚未启动,事件循环不存在 - 不能写在其他方法里(如
onMessage)且没被调用 → 注册逻辑永远不会执行 - 正确写法只有一种:
public function onWorkerStart($worker) { new Crontab('*/5 * * * * *', function() { echo "每5秒执行\n"; }); }
秒级调度必须用6位表达式,少一位就变成分钟级
workerman/crontab 支持秒字段(第1位),但如果你写成 */5 * * * *(5位),它会被当成传统 crontab 解析,最小粒度就是 1 分钟 —— 看似写了“每5秒”,实际是“每5分钟”。
- 每3秒执行:
*/3 * * * * * - 每天凌晨2点整(含秒):
0 0 2 * * *(注意不是0 0 2 * *) - 误写成5位 → 表达式解析失败,任务静默不注册,日志里没有任何提示
- 不支持
@daily等别名,只认标准六字段格式
改完代码必须重启进程,热重载完全无效
Crontab 实例是在进程启动时一次性注册进事件循环的,后续代码变更不会自动 reload。改了表达式、回调函数或参数,旧逻辑照常运行。
- 修改
app/process/Task.php后,必须执行php webman restart - 若用
php webman start -d守护模式,直接改文件不重启,新逻辑永远不生效 - 开发阶段建议先用前台模式
php webman start,方便观察日志和即时验证
多进程阻塞、跨实例重复、耗时任务拖垮整个调度——这些都不是配置问题,而是机制本身决定的。真正要解决它们,得从进程隔离、Redis 锁、动态加载这些层面动手,而不是反复检查 cron 表达式有没有写对。

















