# 消息队列 ## 说明 将之前在定时任务和事件里面的众多方法转移消息队列中,提升系统运行速度。 ## 文件目录结构 ``` ├─crmeb CREMB核心类库 │ ├─jobs 消息队列 ``` ## Queue使用方式 ~~~ Queue::instance()->do('方法名称')->job(类名称::class)->secs('延迟时间(s)')->data(参数1,参数2,····)->push(); do(string $do) 设置任务执行方法,不调用默认执行doJob方法, job(string $job) 设置任务执行类名,必填,例: job(TestJob::class) errorCount(int $errorCount) 执行失败次数,不调用默认3次 data(...$data) 执行数据,无参数可以不调用 secs(int $secs) 延迟执行秒数,不调用加入正常队列,参数不为0加入延迟队列,延迟$secs执行 ~~~ ## 子任务和单任务 ### 子任务 ~~~ 使用do方法时,传入方法名称,执行队列时会执行该类中对应的方法, 例如模板消息队列类,类中有众多发送模板消息的方法,使用do方法调用某个方法执行。 ~~~ ~~~ return Queue::instance()->do('sendOrderTakeSuccess')->job(WechatTemplateJob::class)->data($openid, $order, $title)->push(); ~~~ ~~~ class WechatTemplateJob extends BaseJob { /** * 支付成功发送模板消息 * @param $order * @return bool */ public function sendOrderPaySuccess($openid, $order) { return $this->sendTemplate('ORDER_PAY_SUCCESS', $openid, [ 'first' => '亲,您购买的商品已支付成功', 'keyword1' => $order['order_id'], 'keyword2' => $order['pay_price'], 'remark' => '点击查看订单详情' ], sys_config('site_url') . Route::buildUrl('/pages/order_details/index?order_id=' . $order['order_id'])->suffix('')->domain(false)->build()); } /** * 确认收货发送模板消息 * @param $order * @return bool|mixed */ public function sendOrderTakeSuccess($openid, $order, $title) { return $this->sendTemplate('ORDER_TAKE_SUCCESS', $openid, [ 'first' => '亲,您的订单已收货', 'keyword1' => $order['order_id'], 'keyword2' => '已收货', 'keyword3' => date('Y-m-d H:i:s', time()), 'keyword4' => $title, 'remark' => '感谢您的光临!' ]); } } ~~~ ### 单任务 ~~~ 不使用do方法时,系统会自动调用类中的doJob执行队列,该类只实现了一个功能 例如订单未支付10分钟后发送短信,类中只有一个doJob的方法,队列执行时调用该方法执行。 ~~~ ~~~ Queue::instance()->job(UnpaidOrderSend::class)->secs(600)->data($orderId)->push(); ~~~ ~~~ /** * 未支付10分钟后发送短信 * Class UnpaidOrderSend * @package crmeb\jobs */ class UnpaidOrderSend extends BaseJob { public function doJob($id) { /** @var StoreOrderServices $services */ $services = app()->make(StoreOrderServices::class); $orderInfo = $services->get($id); if (!$orderInfo) { return true; } if ($orderInfo->paid) { return true; } if ($orderInfo->is_del) { return true; } /** @var SmsSendServices $smsServices */ $smsServices = app()->make(SmsSendServices::class); $smsServices->send(true, $orderInfo['user_phone'], ['order_id' => $orderInfo['order_id']], 'ORDER_PAY_FALSE'); return true; } } ~~~ ## 延迟队列 ~~~ 加入消息队列时不调用secs方法,直接加入到队列中,依次执行。 Queue::instance()->job(UnpaidOrderSend::class)->data($orderId)->push();//立即执行未付款发送短信 调用secs方法并传入秒数时,队列加入延迟队列,多少秒后执行该队列。 Queue::instance()->job(UnpaidOrderSend::class)->secs(600)->data($orderId)->push();//600秒后执行未付款发送短信 ~~~