laravel计划任务和异步队列任务,拆分成不同队列,减少计划任务系统压力
2025年7月30日14:10:01
就直说laravel的计划任务,是串行化的一个一个执行的,如果当前需要执行的任务很多的时候,或者当前有任务的执行耗时比较长的时候,
那么一些需要及时处理的就会拖延,导致执行不及时,导致一些业务上的挤压数据。
一般的laravel 跑在fpm的执行计划任务的就是在linux的crontab上添加一条记录
// www 是php的运行用户,避免使用其他用户导致日志写入log导致权限问题
* * * * * sudo -u www /usr/local/php8/bin/php /data/wwwroot/mc/artisan schedule:run >> /data/root.log
laravel的另一个运行方式
php artisan schedule:work & // 单独起一个进行跑计划任务
有人可能想到,如果为了方案1,执行任务拆分到不同的计划任务跑
或者方案2,再起一个进行
跑,但是这里就需要改造的东西很多,
方案1,需要涉及到很多改造
方案2,需要处理竞争锁的,处理数据需要原子性,保障多个计划任务的数据安全性
其实还有一个更好的拆分方案,
就是计划任务+异步任务队列,通过计划任务定时计划任务把异步任务抛到队列中(建议使用redis,队列数据很多,数据库压力增加,laravel做了竞争锁处理,可以跑多个)
根据不同业务把队列拆分成多个,这样耗时长的,需要及时执行就互不影响
class UploadJob implements ShouldQueue
{use Queueable;public int $orderId;/*** Create a new job instance.*/public function __construct(){$this->onQueue('upload');}/*** Execute the job.*/public function handle(): void{}
}
比如有个上传文件到某个地方,比较耗时,每个小时需要执行一次,但是有另一个任务需要计算钱,需要每5分钟扫描一次,这样每个小时的是简单点,就会计算的很慢,导致
计算钱的数据不及时,系统有些不好的表现
那么改造成:
class UploadCommand extends Command
{/*** The name and signature of the console command.** @var string*/protected $signature = 'upload';/*** The console command description.** @var string*/protected $description = '上传脚本';/*** Execute the console command.*/public function handle(): void{Log::withContext([RequestConst::TraceId => generateUuid('upload')]);// 逻辑伪代码$job = new UploadJob();$job->orderId = xxx;dispatch($job);}
}
启动2个队列
php artisan queue:listen --queue=upload --sleep=1 & php artisan queue:listen --queue=upload --sleep=1 & 启动2个不同队列
php artisan queue:listen --queue=upload --sleep=1 & php artisan queue:listen --queue=doOrder --sleep=1 &