普通模式
正如前文介绍的,默认普通模式,所有的定时任务每秒发起一次请求,(但设置了执行频率之后,频率内不会发起请求)。
普通模式下会等到所有请求结束后才会进入下一轮请求,如果有执行时间很长的任务,显然会影响其他任务的执行。
多进程
多进程是v2.0.102后新增的一个小特性,普通模式也支持,只需要传入指定的参数,发起时能同时发起多个,控制器会多出两个参数,分别是总数和当前多进程编号。
在设置任务时设置concurrency
,然后再定时器控制器中也设置concurrency
属性即可。
修改:app/common/command/timer/config.php
'name' => 'http_demo',
'type' => 'site',
'target' => '',
'frequency' => 600,
'concurrency' => 1,
设置控制器:
class ResetPasswordBase extends TimerController
{
protected $frequency = null;
protected $concurrency = 1; // 跟配置文件相同
注意:配置文件中的并发数和控制器中的必须相同,如果不相同,则按照控制器中的为准,大于控制器中指定的请求会直接被放弃。
利用多进程id实现任务分配
例如数据库有一万条数据,一共开启10个进程,如何保证每个进程只读取自己的任务呢?其实很简单,使用任务主键id(整数)取总进程数的余数,跟当前进程id相同的,就是属于该进程的任务。
SELECT *
FROM ul_tasks
WHERE MOD(id, 10) = 2;
// 模型写法
->whereRaw("MOD(id,{$this->concurrency}) = {$this->concurrencyId}")
以上sql就是第二个进程查询属于自己的任务,当然,完全可以使用redis队列来分配任务。
并发模式
版本要求:v2.0.102+
前文提到,普通模式下不同任务会互相影响,需要等到所有任务执行完后才会执行下一轮,如果有一个任务本身是耗时的,另一个任务要求有及时性,就会出现问题。此时可以开启并发模式,开启之后,所有任务之间是互相不影响的。
单个任务重仍然是阻塞的,关于并发不阻塞的模式,见后续说明。
并发阻塞模式
只需要在配置文件timer.php
中,将模式改为parallel
,然后安装workerman/workerman
扩展和workerman/http-client
。
composer require workerman/workerman
composer require workerman/http-client
1.为了更好的使用workerman,需要安装多进程扩展pcntl,并且需要再linux环境才行。
2.windows模式理论上可以正常实现并发和阻塞,但根据作者较少的windows下的workerman开发经验,进程经常会停止。
3.一定要安装event和pcntl等扩展,虽然没有event也能实现workerman的定时器,但似乎经常会卡住。(作者经验,非workerman官方。)
并发不阻塞模式
本模式的理解也很简单,每秒都会发起任务,并且不需要等待上一次任务执行完成。这很容易造成请求积压,本框架暂不实现该模式。
原文标题:并发模式
原文文档:ulthon_admin
原文地址:https://doc.ulthon.com/read/augushong/ulthon_admin/timer-mode/zh-cn/2.x.html
原文平台:奥宏文档