在项目中通常有一些业务,需要执行的时间比较长并且不需要即时得到结果的业务,我们一般使用队列异步来执行。
在tp中使用队列需要先安装think-queue
composer require topthink/think-queue
安装完成后config中增加一个queue.php配置文件
配置如下:
return [
'default' => 'sync',
'connections' => [
'sync' => [
'type' => 'sync',
],
'database' => [
'type' => 'database',
'queue' => 'default',
'table' => 'jobs',
'connection' => null,
],
'redis' => [
'type' => 'redis',
'queue' => 'default',
'host' => '127.0.0.1',
'port' => 6379,
'password' => '',
'select' => 0,
'timeout' => 0,
'persistent' => false,
],
],
下面我会通过两种用法,即同步和异步来介绍。
默认为 ’sync’ 同步执行
在实际业务队列开发时,可先使用同步方式来调试查看处理结果。
return [
'default' => 'sync',
改为 ’redis’ 后变为异步执行
使用redis配置时,需要首先配置好相应redis主机地址和端口号。
return [
'default' => 'redis',
'connections' => [
'redis' => [
'type' => 'redis',
'queue' => 'default',
'host' => '127.0.0.1',
'port' => 6379,
'password' => '',
'select' => 0, // 数据库为db 0
'timeout' => 0, // 连接超时时间
'persistent' => false, // 是否长连接
],
],
app下创建queue目录,创建TestQueue队列处理类
内容如下:
doJob($data);
if ($isJobDone) {
// 任务执行成功 删除任务
$job->delete();
} else {
if ($job->attempts() > 3) {
// 任务重试3次后 删除任务
$job->delete();
}
}
}
/**
* 队列执行 业务处理
* @param $data
* @return bool
*/
private function doJob($data)
{
switch ($data['type']){
case 1:
echo '类型1处理';
dump($data);
break;
case 2:
echo '类型2处理';
dump($data);
break;
}
return true;
}
}
创建一个控制器,来实现加入队列操作。
class Test extends Common
{
public function __construct(App $app)
{
parent::__construct($app);
}
// 测试队列
public function testQueue()
{
// 队列名称
$queueName = 'test';
// 队列的数据
$data = [
'id' => 1,
'name' => '张三',
'gender' => '男',
'type' => 1
];
// 队列处理类
$queueClass = \app\queue\TestQueue::class;
$res = Queue::push($queueClass, $data, $queueName);
dump($res);
}
}
同步可直接查看结果
异步(redis)执行
不再返回执行结果,返回的是随机唯一字符串;可通过监听队列查看执行结果。
启动队列有两种方式。
work方式启动是单进程运行。
php think queue:work --queue test
// test为队列名称
通过命令窗口监听,然后请求加入队列,可看到命令行有相应执行。
命令行参数
这种方式是通过master主进程来监听,当请求进来后启动work子进程来运行上面的work方式启动。
php think queue:listen --queue test
也是通过命令窗口监听,然后请求加入队列,可看到命令行有相应执行。
命令行参数
更推荐listen方式来运行。这种方式更新代码后不需要手动重启。
其他都相同,只是使用later方法,并增加一个延迟时间参数。
// 测试队列
public function testQueue()
{
// 队列名称
$queueName = 'test';
// 队列的数据
$data = [
'id' => 1,
'name' => '张三',
'gender' => '男',
'type' => 1
];
// 队列处理类
$queueClass = \app\queue\TestQueue::class;
// 延迟时间(秒)
$delay = 10;
$res = Queue::later($delay, $queueClass, $data, $queueName);
print_r($res);die;
}
效果:
任务重启
php think queue:restart
清除所有失败任务
php think queue:flush