laravel 消息队列在项目中的应用实例

马克飞 3月前 176

前言

最近在构建公司的统一支付,本想使用阿里云的消息队列,考虑到刚起步,决定先用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

失败任务表创建

  • laravel已经帮我们想好了,运行以下命令就行
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}
  • 为了减少代码耦合度,消息使用数组而不要使用具体对象

最后:写的比较匆忙,有问题可以给我评论一起探讨-_-!

最新回复 (0)
    • 都市菜鸟网
      2
        立即登录 立即注册 
返回