laravel企业级别队列、守护进程以及事件形式发送邮件

412 阅读3分钟

这是我参与11月更文挑战的第3天,活动详情查看:2021最后一次更文挑战

一、邮件管理

在发货后,向用户发邮件。

1.1 创建邮件类

运行命令:php artisan make:mail OrderPost 在这里插入图片描述 在这里插入图片描述

1.2 邮件发送

resources/views/下建一个emails文件夹,并在这个文件夹下新建order-post.blade.php。先写入一点简单的测试数据:

<p>您的单号:{{$order->order_no}} 已经发货</p>

<h4>商品信息:</h4>

<ul>
    @foreach($order->orderDetails()->with('goods')->get() as $detail)
        <li>{{$detail->goods->title}}, 单价为:{{$detail->price}},数量为:{{$detail->num}}</li>
    @endforeach
</ul>

<h5>总付款:{{$order->amount}}</h5>

然后在Mail\OrderPost.php中写入:

<?php

namespace App\Mail;

use Illuminate\Bus\Queueable;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Mail\Mailable;
use Illuminate\Queue\SerializesModels;

class OrderPost extends Mailable
{
    use Queueable, SerializesModels;

    protected $order;
    /**
     * Create a new message instance.
     *
     * @return void
     */
    public function __construct($order)
    {
        $this->order = $order;
    }

    /**
     * Build the message.
     *
     * @return $this
     */
    public function build()
    {
        return $this->view('emails.order-post', [
            'order' => $this->order
        ]);
    }
}

增加订单发货时,发送邮箱: 在这里插入图片描述 增加邮箱配置,邮箱配置可点这里查看。 修改我们第一个用户的邮箱(我们可接收到的邮箱): 在这里插入图片描述


1.3 发送邮件测试

在这里插入图片描述 在这里插入图片描述 可以看到,只要我们发货了,就会给用户邮箱发送发货通知。

1.4 优化

在短信发送中,是比较耗时的,我们不能一直等着,需要采用队列,让它自己去慢慢等发送。

修改OrderController.php在这里插入图片描述send改为queue,但是队列的话,我们这边还没配置,所以我们现在进行对队列的配置。

1、生成队列迁移文件

运行命令php artisan queue:table 在这里插入图片描述 在这里插入图片描述 运行命令php artisan migrate执行迁移文件: 在这里插入图片描述

可以看到生成了一个jobsfailed_jobs的表,就会把发邮件这块功能放到这个迁移文件里面去排队,这样如果发的邮件比较多的话,也不会很慢,它发一个删一个。当有失败的话它会放到failed_jobs这个表中: 在这里插入图片描述

2、修改队列配置

.env中修改队列驱动: 在这里插入图片描述

3、运行队列测试

在不运行队列之前,我们使用send发送邮箱得到的响应是: 在这里插入图片描述 可以看到1312ms。 接着我们运行队列,看看时间上优化了多少: 运行命令php artisan queue:work 在这里插入图片描述 在这里插入图片描述 138ms可以看到整整优化快了10倍,这还不算邮件多的情况。


在这里插入图片描述 但是可以看到我们终端一直开着,万一不小断了,就没了,所以肯定是不能出现这种情况的。 所以我们配置守护进程。

4、配置守护进程

进入目录:/etc/supervisor/conf.d在这里插入图片描述 运行命令sudo nano jshopapi.conf创建jshopapi.conf文件: 在这里插入图片描述 接着将以下内容复制进去:

[program:jshopapi]
process_name=%(program_name)s_%(process_num)02d
command=php /home/vagrant/code/shopProjectApi/artisan queue:work
autostart=true
autorestart=true
user=vagrant
numprocs=2
redirect_stderr=true 
stdout_logfile=/home/vagrant/code/shopProjectApi/storage/logs/worker.log
stopwaitsecs=3600

在这里插入图片描述 在这里插入图片描述 复制进去后control+x退出,退出的时候会问你是否保存,你就保存: 在这里插入图片描述 输入y回车,接着输入命令sudo supervisorctl update启动守护进程: 在这里插入图片描述 查看进程状态: 在这里插入图片描述 看见有两个进程在守护了。

再去测试发送邮件: 在这里插入图片描述 可以看到进程再跑,而不是通过终端。守护进程会一直在跑,就算意外终止,它也会重启跑起来。 也可以看到日志: 在这里插入图片描述


5、发货当成事件来处理

1、添加监听器 在app/Providers/EventServiceProvider.php中进行注册:

'App\Events\OrderPost' => [
            'App\Listeners\SendEmailToOrderUser',
        ],

在这里插入图片描述

2、生成事件和监听器 运行命令:php artisan event:generate 在这里插入图片描述 在这里插入图片描述 3、修改发货逻辑 将不在控制器里去发货直接使用发货事件去发货。

        // 发货 使用事件分发
        event(new \App\Events\OrderPost(
            $order, 
            $request->input('express_type'), 
            $request->input('express_no')
        ));

在这里插入图片描述 我们采用事件分发,将订单、快递类型以及快递单号传到事件类中。 所以在Events\OrderPost.php中接收这些参数: 在这里插入图片描述


接着Listeners\SendEmailToOrderUser.php修改监听者里面的处理逻辑:

<?php

namespace App\Listeners;

use App\Events\OrderPost;
use App\Mail\OrderPost as MailOrderPost;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Queue\InteractsWithQueue;
use Illuminate\Support\Facades\Mail;

class SendEmailToOrderUser
{

    /**
     * Create the event listener.
     *
     * @return void
     */
    public function __construct()
    {
        
    }

    /**
     * Handle the event.
     *
     * @param  OrderPost  $event
     * @return void
     */
    public function handle(OrderPost $event)
    {
        $event->order->express_type = $event->express_type;
        $event->order->express_no = $event->express_no;
        $event->order->status = 3; // 发货状态
        $event->order->save();

        // 发货之后,邮件提醒
        Mail::to($event->order->user)->queue(new MailOrderPost($event->order));
    }
}

在这里插入图片描述


4、使用事件方式测试 在这里插入图片描述 在这里插入图片描述

在学习的php的路上,如果你觉得本文对你有所帮助的话,那就请关注点赞评论三连吧,谢谢,你的肯定是我写博的另一个支持。