Swoole在ThinkPHP 5.1中实现毫秒级定时任务需满足三前提:Swoole≥v4.8.0且timer启用、仅Worker进程(onWorkerStart)中启动、协程模式下优先用CoroutineTimer;支持after单次与tick周期调度,须手动clear防泄漏,禁用register_shutdown_function,并避免同步阻塞操作。
在 ThinkPHP 5.1 项目中,用 Swoole 实现毫秒级定时任务调度,本质是绕过 Linux crontab 的分钟级限制,直接在 PHP 进程内嵌入高精度异步定时器。它不替代 crontab,而是补充——适合需亚秒响应、动态启停、与业务强耦合的任务,比如实时库存锁释放、心跳保活、传感器数据采集等。
不是装了 Swoole 就能用定时器。以下三点缺一不可:
php --ri swoole 查看 timer: enabled 和 version);onWorkerStart 回调里),放在 onStart 或命令行入口全局位置会静默失败;enable_coroutine => true),优先选用 SwooleCoroutineTimer::tick(),避免传统 timer ID 管理和 Worker 数量限制。推荐通过自定义 Artisan 风格命令实现,便于开发与部署统一管理:
application/command/TimerStart.php,继承 thinkconsoleCommand;execute() 方法中实例化 swoole_server 或直接使用 SwooleTimer(CLI 模式下可省略 server);onWorkerStart 回调中,且仅限 $worker_id === 0 的 Worker 启动(避免重复触发);swoole_timer_tick(200, function ($timer_id) {<br> Db::name('order')->where('status', 0)->where('create_time', '<', time() - 1800)->update(['status' => 2]);<br>});
根据业务是否重复,选择对应 API:
swoole_timer_after(3000, function () { Log::error('超时未支付'); }); —— 自动销毁,无需 clear;$tid = swoole_timer_tick(150, function ($timer_id) { cache('status', getDeviceStatus()); });,后续需手动 swoole_timer_clear($tid) 停止;swoole_timer_clear($tid),再新建一个。毫秒级高频触发对资源更敏感,稍不注意就会泄漏或阻塞:
swoole_timer_tick() 返回的 $timer_id 必须被显式保存,并在不再需要时调用 swoole_timer_clear();file_get_contents、sleep、未加 go 的数据库查询),否则整个 Worker 事件循环卡死;SwooleCoroutineHttpClient 或 Db::connect()->query(...)(TP5.1 + Swoole 协程适配需额外配置);register_shutdown_function:在启动前加 ini_set('register_shutdown_function', '0');,防止进程退出时定时器被截断。