前言
最近在构建公司的统一支付,本想使用阿里云的消息队列,考虑到刚起步,决定先用laravel自带的队列使用redis来处理,因为laravel对不同的对队实现了统一的API所以后续转阿里云也挺方便,那就愉快的这么定了
配置
这里的配置是针对laravel版本7以上的,更早版本可能配置变量会有不同,需要注意
- 参见 app\config\queue.php,在.env文件中配置 QUEUE_CONNECTION 为 redis (在5版本中这个常量名为QUEUE_DRIVER,还有其他的配置也不同,这里建议要多项目使用队列最好进行版本统一,当然不同版本修改到相同配置也是可行的)
- 根据实际情况配置.env的以下常量:
- REDIS_HOST
- REDIS_PASSWORD
- REDIS_PORT
- REDIS_DB
- REDIS_CACHE_DB
失败任务表创建
php artisan queue:failed-table
php artisan migrate
创建队列任务
php artisan make:job UnifiedPay
<?php
namespace App\Jobs;
use Illuminate\Bus\Queueable;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Foundation\Bus\Dispatchable;
use Illuminate\Queue\InteractsWithQueue;
use Illuminate\Queue\SerializesModels;
use Illuminate\Support\Facades\Log;
class UnifiedPay implements ShouldQueue
{
use Dispatchable, InteractsWithQueue, Queueable, SerializesModels;
protected $data;
public $tries = 3; // 任务尝试次数
public $maxExceptions = 3; // 触发3次异常,任务失败
public $timeout = 60; // 任务运行的超时时间;单位:秒
/**
* Create a new job instance.
*
* @return void
*/
public function __construct(array $data)
{
$this->data = $data;
}
/**
* Execute the job.
*
* @return void
*/
public function handle()
{
// 自己写业务逻辑
Log::info('加入队列成功');
}
/**
* 任务未能处理
*
* @param Exception $exception
* @return void
*/
public function failed(\Exception $exception)
{
// 给用户发送失败通知, 等等...
}
}
<?php
namespace App\Http\Controllers\UniteOpen;
use App\Http\Controllers\Controller;
use Illuminate\Http\Request;
use App\Jobs\UnifiedPay;
class PayController extends Controller
{
public function citicBankNotify(Request $request)
{
UnifiedPay::dispatch($request->all())->onQueue('unified_pay');
return true;
}
}
上面控制器方法调用一次就会产生一条队列任务;
消费队列任务
php artisan queue:work --queue=unified_pay
- 去redis查看,会看到队列任务消失了,执行输出如下
[2020-05-11 16:58:25] Processing: App\Jobs\UnifiedPay
array(2) {
["s"]=>
string(29) "/api/v1/pay/citic-bank-notify"
["aa"]=>
string(3) "456"
}
队列消费成功[2020-05-11 16:58:25] Processed: App\Jobs\UnifiedPay
[2020-05-11 16:58:37] Processing: App\Jobs\UnifiedPay
array(2) {
["s"]=>
string(29) "/api/v1/pay/citic-bank-notify"
["aa"]=>
string(4) "4567"
}
队列消费成功[2020-05-11 16:58:37] Processed: App\Jobs\UnifiedPay
[2020-05-11 16:58:47] Processing: App\Jobs\UnifiedPay
array(2) {
["s"]=>
string(29) "/api/v1/pay/citic-bank-notify"
["aa"]=>
string(5) "45679"
}
队列消费成功[2020-05-11 16:58:47] Processed: App\Jobs\UnifiedPay
A项目生产队列 B项目消费队列处理
- 两个项目需要同一个 queue 的 connection
- 任务生产者和任务订阅者配置同一个队列名称 {queue}
- 任务生产者和任务订阅者有一个相同的 job,类名和配置一样,不一样的是 handle 里面的内容
- 任务订阅者监听的时候要指定参数–queue={queue}
- 为了减少代码耦合度,消息使用数组而不要使用具体对象
最后:写的比较匆忙,有问题可以给我评论一起探讨-_-!