laravel 通过队列处理 自动删除30分钟未付款订单

这个问题大概几种解决方案 1 基于linux cron定时任务 (laravel也有针对cron比较优秀的解决方案) 2 基于队列的延时执行 3 通过redis的数据过期 等

Posted by 昆山吴彦祖 on 2019.03.29

这个问题大概几种解决方案  1 基于linux cron定时任务 (laravel也有针对cron比较优秀的解决方案) 2 基于队列的延时执行  3 通过redis的数据过期 等


这次采用的是基于队列任务的延时执行,相较于cron 这种方案在执行时效性和后期拓展性上更胜一筹,官方推荐采用redis作为laravel队列服务的驱动,但是因为这次案子比较急(没怎么用过redis,懒得去配置),我就直接采用了mysql作为驱动


首先我们进行队列配置

1、更改系统默认队列驱动(.env)

QUEUE_CONNECTION=database


2、创建存储队列数据的sql

php artisan queue:table
php artisan migrate


3、创建任务文件

php artisan make:job OrderJob


4、编辑任务文件,对任务进行一些安全性配置(参考

namespace App\Jobs;

use Illuminate\Bus\Queueable;
use Illuminate\Queue\SerializesModels;
use Illuminate\Queue\InteractsWithQueue;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Foundation\Bus\Dispatchable;

use App\Order;
//use Log;

class OrderJob implements ShouldQueue
{
    use Dispatchable, InteractsWithQueue, Queueable, SerializesModels;
	public $tries = 5;//最大尝试次数
	public $timeout = 5;//最大尝试时间
	public $order;
    /**
     * Create a new job instance.
     *
     * @return void
     */
    public function __construct(Order $order)
    {
        //
		$this->order = $order;/* 
		Log::info('队列任务初始化了');
		Log::info($this->order);
		Log::info(now()); */
    }

    /**
     * Execute the job.
     *
     * @return void
     */
    public function handle()
    {
		/* Log::info('队列任务执行了');
		Log::info($this->order);
		Log::info(now()); */
        // 判断订单状态是否为1,自动删除未支付订单
		if($this->order->status ==1){
			$this->order->delete();
		}
    }
}


5、在合适的时机进行任务分发,我是在模型观察者中监测订单的创建,同时进行任务分发

namespace App\Observers;

use App\Order;
use App\OrderItem;
use App\CensusOrderDate;
use App\CensusOrderArea;
use Carbon\Carbon;
use EasyWeChat\Factory;
use Log;
use App\Jobs\OrderJob;


class OrderObserver
{
    /**
     * Handle the order "created" event.
     *
     * @param  \App\Order  $order
     * @return void
     */
    public function created(Order $order)
    {
        //
		// 分发延时30min任务到队列
		OrderJob::dispatch($order)->delay(now()->addMinutes(30));
    }
}


到这一步结束的时候,我们基本配置就已经完成了,然后可以通过laravel自带的队列进程来进行测试了

php artisan queue:work

如果测试没有定时删除,那检查前面几步看看哪里错了。



接下来要配置 Supervisor 

​为了保持队列进程 queue:work 持续在后台运行,需要使用进程守护程序Supervisor 

​官方文档提供了Ubuntu的快捷安装指令,我是centos7

​1、centos安装Supervisor 

#sudo su 
# yum install epel-release
# yum install -y supervisor
# systemctl enable supervisord # 开机自启动
# systemctl start supervisord # 启动supervisord服务

# systemctl status supervisord # 查看supervisord服务状态
# ps -ef|grep supervisord # 查看是否存在supervisord进程


​2、配置Supervisor 

找到Supervisor 主配置文件,我安装完成后配置文件是/etc/Supervisord.conf,和laravel官方文档的不太一样,不知道是不是Supervisor 针对Ubuntu和centos的不同版本造成的。

打开查看:

[include]
files = supervisord.d/*.ini

可以找到配置文件引入目录和引入后缀,进入引入目录,创建一个子配置文件laravel-worker.ini

[program:laravel-worker]
process_name=%(program_name)s_%(process_num)02d
command=php /www/wwwroot/blog/artisan queue:work --sleep=3 --tries=3
autostart=true autorestart=true user=blog numprocs=8 redirect_stderr=true stdout_logfile=/www/wwwroot/blog/worker.log


3、重启supervisor

# systemctl restart supervisord


到这一步,我们基本就可以收工了


如果想记录处理失败的任务

​1、创建相关数据表

php artisan queue:failed-table
php artisan migrate

创建完成后,队列任务执行失败会被记录到这个表


队列