当前位置:首页 > PHP教程 > php高级应用 > 列表

php调用Workerman管理定时任务详解

发布:smiling 来源: PHP粉丝网  添加日期:2026-03-25 19:49:18 浏览: 评论:0 

Workerman 是一个高性能的 PHP Socket 框架,常用于开发实时通信、长连接服务等场景,本文主要来和大家聊聊如何使用Workerman管理定时任务,感兴趣的小伙伴可以参考一下。

在 Workerman 中管理定时任务(启动、重启、停止)需要结合 Timer 类和 Worker 进程的生命周期。以下是详细操作步骤:

1. 启动定时任务

定时任务通常在 onWorkerStart 回调中注册,Worker 进程启动后自动执行。

代码示例:

  1. use Workerman\Worker; 
  2. use Workerman\Timer; 
  3.    
  4. require_once __DIR__ . '/vendor/autoload.php'
  5.    
  6. $worker = new Worker(); 
  7.    
  8. // Worker 进程启动时注册定时任务 
  9. $worker->onWorkerStart = function ($worker) { 
  10.     // 启动一个每秒执行的定时任务 
  11.     $timerId = Timer::add(1, function () { 
  12.         echo "Running task at " . date('Y-m-d H:i:s') . "\n"
  13.     }); 
  14.       
  15.     // 保存定时器 ID(用于后续操作) 
  16.     $worker->timerId = $timerId
  17. }; 
  18.    
  19. Worker::runAll(); 

2. 停止定时任务

通过 Timer::del() 方法停止指定定时器。

代码示例:

  1. // 停止单个定时任务 
  2. $timerId = Timer::add(2, function () { /* ... */ }); 
  3. Timer::del($timerId); 
  4.    
  5. // 停止所有定时任务 
  6. Timer::delAll(); // 慎用!会停止当前进程所有定时器 
  7. 动态停止示例 
  8. $worker->onMessage = function ($connection$datause ($worker) { 
  9.     // 收到特定指令时停止定时任务 
  10.     if ($data === 'stop') { 
  11.         Timer::del($worker->timerId); 
  12.         $connection->send("定时任务已停止"); 
  13.     } 
  14. }; 

3. 重启定时任务

重启需要先停止旧任务,再重新注册新任务。

代码示例

  1. // 假设 $oldTimerId 是已存在的定时器 ID 
  2. $newTimerId = Timer::add(5, function () { /* 新任务逻辑 */ }); 
  3. Timer::del($oldTimerId); // 停止旧任务 
  4.    
  5. // 或通过闭包动态更新 
  6. $worker->onWorkerStart = function ($worker) { 
  7.     $worker->timerId = Timer::add(1, function () use ($worker) { 
  8.         static $count = 0; 
  9.         $count++; 
  10.         echo "执行次数: $count\n"
  11.           
  12.         // 达到条件后重启任务(例如修改间隔时间) 
  13.         if ($count >= 5) { 
  14.             Timer::del($worker->timerId); 
  15.             $worker->timerId = Timer::add(2, function () {  
  16.                 echo "重启后的任务\n";  
  17.             }); 
  18.         } 
  19.     }); 
  20. }; 

4. 多进程环境注意事项

单例任务:如果只需要一个进程运行定时任务,在 onWorkerStart 中通过进程 ID 控制:

  1. $worker->onWorkerStart = function ($worker) { 
  2.     if ($worker->id === 0) { // 仅第一个进程执行 
  3.         Timer::add(1, function () { /* ... */ }); 
  4.     } 
  5. }; 

分布式部署:多台服务器时,使用 Redis 锁或数据库标记确保任务唯一性。

5. 通过命令行管理 Worker

Workerman 的定时任务依赖于 Worker 进程,因此可通过管理 Worker 间接控制定时任务:

操作 命令 说明

启动 php yourfile.php start 启动 Worker 进程,定时任务自动运行

平滑重启 php yourfile.php reload 重新加载业务代码,定时任务会重新初始化

强制停止 php yourfile.php stop 停止所有 Worker 进程(立即终止)

优雅停止 php yourfile.php stop -g 等待当前任务完成后再停止

6. 动态控制定时任务(高级)

结合 HTTP 接口或自定义信号动态管理:

示例:通过 HTTP 接口控制

  1. $httpWorker = new Worker('http://0.0.0.0:8080'); 
  2. $httpWorker->onMessage = function ($connection$request) { 
  3.     $action = $request->get('action'); 
  4.       
  5.     switch ($action) { 
  6.         case 'start'
  7.             $timerId = Timer::add(1, function () { /* ... */ }); 
  8.             $connection->send("定时任务 ID: $timerId"); 
  9.             break
  10.         case 'stop'
  11.             $timerId = $request->get('timer_id'); 
  12.             Timer::del($timerId); 
  13.             $connection->send("已停止任务"); 
  14.             break
  15.     } 
  16. }; 

示例:通过信号控制

  1. // 注册自定义信号 
  2. Worker::$onMasterReload = function () { 
  3.     // 收到 SIGUSR1 信号时重启某个任务 
  4.     Timer::del($oldTimerId); 
  5.     $newTimerId = Timer::add(3, function () { /* ... */ }); 
  6. }; 

7. 注意事项

持久化存储:定时器 ID 保存在内存中,进程重启后会丢失,需外部存储(如 Redis)记录关键任务状态。

原子操作:多进程操作时,使用锁机制避免竞争条件。

异常处理:

  1. Timer::add(1, function () { 
  2.     try { 
  3.         // 业务逻辑 
  4.     } catch (Throwable $e) { 
  5.         echo "定时任务异常: " . $e->getMessage(); 
  6.     } 
  7. }); 

总结

操作 方法 场景

启动 Timer::add() Worker 启动时自动注册

停止 Timer::del() 或 Timer::delAll() 动态终止指定或全部任务

重启 先 del() 再 add() 修改间隔时间或任务逻辑

全局控制 命令行 start/stop/reload 管理整个 Worker 进程生命周期

Tags: php调用Workerman php定时任务

分享到: