Skip to content

Laravel Crontab 支持的最小单位是分钟,怎么实现秒级执行的需求呢?

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

需求描述

今天接到一个需求,每三秒钟给客户端推送一次最新的在线人数。

分析

每三秒钟?要这么频繁吗?之前的最小颗粒度是每分钟哇。

调研了一波发现,我们可以结合异步任务的delay来实现。

核心代码

在 onQueue()函数后面调用 delay()函数

delay指定了延迟多久执行

php
XxxxxJob::dispatch()     ->onQueue(QueueNameBuilder::getName(QueueNameBuilder::PUSH_DATING_COUNT))     ->delay(now()->addSeconds($delay));

需求实现

比如我们的需求是,每三秒钟给客户端推送一次数据。

我的设计是这样的:

异步任务代码

php
<?php namespace App\Console\Crontab;
use App\Jobs\PushDatingCountJob;
use App\Model\House\HouseOpen;
use App\Model\Queue\QueueNameBuilder;
class PushDatingCount extends BaseCrontab {
const RATE_SECOND = 3;
//每三秒发送一次 延迟实现     public
function __invoke()     {         $times = 60 / self::RATE_SECOND;
$delayTimes = [];
for ($i = 0;
$i < $times;
$i++) {             $delayTimes[] = $i * 3;
}         foreach ($delayTimes as $delay) {             PushDatingCountJob::dispatch()                 ->onQueue(QueueNameBuilder::getName(QueueNameBuilder::PUSH_DATING_COUNT))                 ->delay(now()->addSeconds($delay));
}
}
}

Kernel

php
<?php namespace App\Console;
. . .
class Kernel extends ConsoleKernel {     /**      * The Artisan commands provided by your application.      *      * @var array      */     protected $commands = [         //     ];
/**      * Define the application's command schedule.      *      * @param \Illuminate\Console\Scheduling\Schedule $schedule      * @return void      */     protected
function schedule(Schedule $schedule)     {         .         .         .         //每分钟执行一次         $schedule->call(new PushDatingCount())             ->cron("* * * * *")             ->name("push_dating_count")             ->onOneServer();
}     /**      * Register the commands
for the application.      *      * @return void      */     protected
function commands()     {         $this->load(__DIR__ . '/Commands');
require base_path('routes/console.php');
}
}

通过这个思路我们就实现了需求。

更多的使用技巧

本地测试阶段不方面使用异步任务队列怎么办呢?

我们可以使用dispatchNow()

比如:

本地执行,不使用异步队列的情况:

php
UserConfirmForAdmin::dispatchNow([             'data' => $data,             'adminId' => $adminId,         ]);

使用异步任务队列执行的情况:

php
UserConfirmForAdmin::dispatch([             'data' => $data,             'adminId' => $adminId,         ])->onQueue(QueueNameBuilder::getName(QueueNameBuilder::USER_CONFIRM_FOR_ADMIN));

如何可视化查询异步任务的执行情况呢?

我们可以使用 horizon

我们通过仪表盘能够非常方便的进行数据监控,查看数据指标,查看最近失败的异步任务,可以通过后台重新执行异步任务

image.png

重点说一下执行失败的异步任务,后台是支持查看数据参数的,方便我们定位问题。

image.png

硬核文章推荐

PHP转Go 2021年年中总结

如何第一时间收到接口报错?不用测试妹子再质疑你是不是接口挂了。

Git使用实战:多人协同开发,紧急修复线上bug的Git操作指南。

性能优化反思:不要在for循环中操作DB

性能优化反思:不要在for循环中操作DB 进阶版

最后

👍🏻:觉得有收获请点个赞鼓励一下!

🌟:收藏文章,方便回看哦!

💬:评论交流,互相进步!

AI 应用开发训练营 · 现在开始

别只收藏 AI 文章,今天就做出第一个能上线的项目

文章解决认知,项目才证明能力。把 Agent、RAG、MCP 变成可运行、可展示、可面试表达的成果,现在就从一次岗位准备度自测开始。

立即开始 AI 岗位准备度自测 查看训练营路线
真实学员成果先看成果,再决定是否开始 →
  1. 01选方向
  2. 02做项目
  3. 03出成果
  4. 04拿面试