毫秒级定时任务
基于Swoole的毫秒定时器,封装的定时任务,取代
Linux
的Crontab
。
1.创建定时任务类。
- namespace App\Jobs\Timer;
- use App\Tasks\TestTask;
- use Swoole\Coroutine;
- use Hhxsv5\LaravelS\Swoole\Task\Task;
- use Hhxsv5\LaravelS\Swoole\Timer\CronJob;
- class TestCronJob extends CronJob
- {
- protected $i = 0;
- // !!! 定时任务的`interval`和`isImmediate`有两种配置方式(二选一):一是重载对应的方法,二是注册定时任务时传入参数。
- // --- 重载对应的方法来返回配置:开始
- public function interval()
- {
- return 1000;// 每1秒运行一次
- }
- public function isImmediate()
- {
- return false;// 是否立即执行第一次,false则等待间隔时间后执行第一次
- }
- // --- 重载对应的方法来返回配置:结束
- public function run()
- {
- \Log::info(__METHOD__, ['start', $this->i, microtime(true)]);
- // do something
- // sleep(1); // Swoole < 2.1
- Coroutine::sleep(1); // Swoole>=2.1 run()方法已自动创建了协程。
- $this->i++;
- \Log::info(__METHOD__, ['end', $this->i, microtime(true)]);
- if ($this->i >= 10) { // 运行10次后不再执行
- \Log::info(__METHOD__, ['stop', $this->i, microtime(true)]);
- $this->stop(); // 终止此任务
- // CronJob中也可以投递Task,但不支持Task的finish()回调。
- // 注意:
- // 1.参数2需传true
- // 2.config/laravels.php中修改配置task_ipc_mode为1或2,参考 https://wiki.swoole.com/wiki/page/296.html
- $ret = Task::deliver(new TestTask('task data'), true);
- var_dump($ret);
- }
- // throw new \Exception('an exception');// 此时抛出的异常上层会忽略,并记录到Swoole日志,需要开发者try/catch捕获处理
- }
- }
2.注册定时任务类。
- // 在"config/laravels.php"注册定时任务类
- [
- // ...
- 'timer' => [
- 'enable' => true, // 启用Timer
- 'jobs' => [ // 注册的定时任务类列表
- // 启用LaravelScheduleJob来执行`php artisan schedule:run`,每分钟一次,替代Linux Crontab
- // \Hhxsv5\LaravelS\Illuminate\LaravelScheduleJob::class,
- // 两种配置参数的方式:
- // [\App\Jobs\Timer\TestCronJob::class, [1000, true]], // 注册时传入参数
- \App\Jobs\Timer\TestCronJob::class, // 重载对应的方法来返回参数
- ],
- 'max_wait_time' => 5, // Reload时最大等待时间
- ],
- // ...
- ];
3.注意在构建服务器集群时,会启动多个定时器
,要确保只启动一个定期器,避免重复执行定时任务。
4.LaravelS v3.4.0
开始支持热重启[Reload]定时器
进程,LaravelS 在收到SIGUSR1
信号后会等待max_wait_time
(默认5)秒再结束进程,然后Manager
进程会重新拉起定时器
进程。