目次
连接 Vs. 队列
驱动的必要设置
数据库
Redis
其它队列驱动的依赖扩展包
创建任务
生成任务类
任务类结构
接続とキュー
必要なドライバ設定
その他のキュー ドライバー依存関係拡張パッケージ
タスクの作成
タスククラスの生成
タスク クラスの構造
分发任务
延迟分发
自定义队列 & 连接
分发任务到指定队列
分发任务到指定连接
指定任务最大尝试次数 / 超时值
最大尝试次数
超时
错误处理
运行队列处理器
指定连接 & 队列
资源注意事项
队列优先级
队列处理器 & 部署
任务过期 & 超时
任务过期
队列处理器超时
队列进程睡眠时间
Supervisor 配置
安装 Supervisor
配置 Supervisor
启动 Supervisor
处理失败的任务
清除失败任务
重试失败任务
任务事件
ホームページ バックエンド開発 PHPチュートリアル Laravelのキューシステムの紹介

Laravelのキューシステムの紹介

Apr 16, 2018 pm 03:26 PM
laravel 導入

この記事では主にLaravelのキューシステムの紹介をしていますが、これは参考になると思いますので、必要な友達は参考にしてください

LaravelキューはBeanstalkなどのさまざまなバックグラウンドキューサービスに統合されたAPIを提供します。 Amazon SQS、Redis、さらにはその他のリレーショナル データベース ベースのキュー。 キューの目的は、電子メールの送信など、時間のかかるタスクの処理を遅らせ、Web リクエストと応答時間を大幅に短縮することです。

キュー設定ファイルは config/queue.php に保存されます。 このファイルには、データベース、Beanstalkd、Amazon SQS、Redis、同期 (ローカル使用) ドライバーなどの各キュー ドライバーの設定が含まれています。 また、キューを破棄するタスク用の null キュー ドライバーも含まれています。 config/queue.php。 每一种队列驱动的配置都可以在该文件中找到, 包括数据库, Beanstalkd, Amazon SQS, Redis, 以及同步(本地使用)驱动。 其中还包含了一个null队列驱动用于那些放弃队列的任务。


连接 Vs. 队列

在开始使用 Laravel 队列前,弄明白 「连接」 和 「队列」 的区别是很重要的。在你的 config/queue.php 配置文件里, 有一个 connections 配置选项。 这个选项给 Amazon SQS, Beanstalk ,或者 Redis 这样的后端服务定义了一个特有的连接。不管是哪一种,一个给定的连接可能会有多个「队列」,而 「队列」可以被认为是不同的栈或者大量的队列任务。

要注意的是, queue 配置文件中每个连接的配置示例中都包含一个 queue 属性。这是默认队列,任务被发给指定连接的时候会被分发到这个队列中。换句话说,如果你分发任务的时候没有显式定义队列,那么它就会被放到连接配置中 queue 属性所定义的队列中:

// 这个任务将被分发到默认队列...dispatch(new Job);// 这个任务将被发送到「emails」队列...dispatch((new Job)->onQueue('emails'));
ログイン後にコピー

有些应用可能不需要把任务发到不同的队列,而只发到一个简单的队列中就行了。但是把任务推到不同的队列仍然是非常有用的,因为 Laravel 队列处理器允许你定义队列的优先级,所以你能给不同的队列划分不同的优先级或者区分不同任务的不同处理方式了。比如说,如果你把任务推到 high 队列中,你就能让队列处理器优先处理这些任务了:

php artisan queue:work --queue=high,default
ログイン後にコピー


驱动的必要设置

数据库

要使用 database 这个队列驱动的话, 你需要创建一个数据表来存储任务,你可以用 queue:table 这个 Artisan 命令来创建这个数据表的迁移。 当迁移创建好以后,就可以用 migrate 这条命令来创建数据表:

php artisan queue:table

php artisan migrate
ログイン後にコピー

Redis

为了使用 redis 队列驱动, 你需要在你的配置文件 config/database.php 中配置Redis的数据库连接

如果你的 Redis 队列连接使用的是 Redis 集群, 你的队列名称必须包含 key hash tag 。 这是为了确保所有的 redis 键对于一个给定的队列都置于同一哈希中:

'redis' => [
    'driver' => 'redis',
    'connection' => 'default',
    'queue' => '{default}',
    'retry_after' => 90,],
ログイン後にコピー

其它队列驱动的依赖扩展包

在使用列表里的队列服务前,必须安装以下依赖扩展包:


  • Amazon SQS: aws/aws-sdk-php ~3.0

  • Beanstalkd: pda/pheanstalk ~3.0

  • Redis: predis/predis ~1.0



创建任务


生成任务类

在你的应用程序中,队列的任务类都默认放在 app/Jobs 目录下,如果这个目录不存在,那当你运行 make:job artisan 命令时目录就会被自动创建。 你可以用以下的 Artisan 命令来生成一个新的队列任务:

php artisan make:job SendReminderEmail
ログイン後にコピー

生成的类实现了 IlluminateContractsQueueShouldQueue 接口,这意味着这个任务将会被推送到队列中,而不是同步执行。


任务类结构

任务类的结构很简单,一般来说只会包含一个让队列用来调用此任务的 handle 方法。我们来看一个示例的任务类,这个示例里,假设我们管理着一个播客发布服务,在发布之前需要处理上传播客文件:

<?phpnamespace App\Jobs;use App\Podcast;use App\AudioProcessor;use Illuminate\Bus\Queueable;use Illuminate\Queue\SerializesModels;use Illuminate\Queue\InteractsWithQueue;use Illuminate\Contracts\Queue\ShouldQueue;class ProcessPodcast implements ShouldQueue{
    use InteractsWithQueue, Queueable, SerializesModels;

    protected $podcast;

    /**
     * 创建一个新的任务实例。
     *
     * @param  Podcast  $podcast
     * @return void
     */
    public function __construct(Podcast $podcast)
    {
        $this->podcast = $podcast;
    }

    /**
     * 运行任务。
     *
     * @param  AudioProcessor  $processor
     * @return void
     */
    public function handle(AudioProcessor $processor)
    {
        // Process uploaded podcast...
    }}
ログイン後にコピー

注意,在这个例子中,我们在任务类的构造器中直接传递了一个 Eloquent 模型。因为我们在任务类里引用了 SerializesModels

🎜

接続とキュー

🎜 Laravel キューを使い始める前に、「接続」と「キュー」の違いを理解することが重要です。 config/queue.php 設定ファイルには、connections 設定オプションがあります。 このオプションは、Amazon SQS、Beanstalk、Redis などのバックエンド サービスへの一意の接続を定義します。いずれの場合も、特定の接続に対して複数の「キュー」が存在する可能性があり、「キュー」はさまざまなスタック、またはキューに入れられた多数のタスクと考えることができます。 🎜🎜queue 設定ファイル内の各接続の設定例には、queue 属性が含まれていることに注意してください。これはデフォルトのキューであり、タスクは指定された接続に送信されるとこのキューに分散されます。つまり、タスクを分散するときにキューを明示的に定義しない場合、タスクは接続構成の queue 属性で定義されたキューに配置されます。 🎜
<?phpnamespace App\Http\Controllers;use App\Jobs\ProcessPodcast;use Illuminate\Http\Request;use App\Http\Controllers\Controller;class PodcastController extends Controller{
    /**
     * 保存播客。
     *
     * @param  Request  $request
     * @return Response
     */
    public function store(Request $request)
    {
        // 创建播客...

        dispatch(new ProcessPodcast($podcast));
    }}
ログイン後にコピー
ログイン後にコピー
🎜一部のアプリケーションでは、その必要がない場合があります。タスクは別のキューに送信されますが、送信されるのは単純なキューのみです。ただし、タスクを別のキューにプッシュすることは依然として非常に便利です。Laravel キュー ハンドラーではキューの優先順位を定義できるため、異なるキューに異なる優先順位を割り当てたり、タスクごとに異なる処理方法を区別したりできます。たとえば、タスクを high キューにプッシュすると、キュー プロセッサに次のタスクを優先させることができます: 🎜
<?phpnamespace App\Http\Controllers;use Carbon\Carbon;use App\Jobs\ProcessPodcast;use Illuminate\Http\Request;use App\Http\Controllers\Controller;class PodcastController extends Controller{
    /**
     * 保存一个新的播客。
     *
     * @param  Request  $request
     * @return Response
     */
    public function store(Request $request)
    {
        // 创建播客...

        $job = (new ProcessPodcast($podcast))
                    ->delay(Carbon::now()->addMinutes(10));

        dispatch($job);
    }}
ログイン後にコピー
ログイン後にコピー
🎜🎜🎜

必要なドライバ設定

< h4>データベース🎜 database キュー ドライバーを使用するには、タスクを保存するためのデータ テーブルを作成する必要があります。 queue:table アーティザン コマンドを使用して、このテーブルの移行を作成できます。データ表。 移行が作成されたら、merge コマンドを使用してデータ テーブルを作成できます: 🎜
<?phpnamespace App\Http\Controllers;use App\Jobs\ProcessPodcast;use Illuminate\Http\Request;use App\Http\Controllers\Controller;class PodcastController extends Controller{
    /**
     * 保存一个新的播客。
     *
     * @param  Request  $request
     * @return Response
     */
    public function store(Request $request)
    {
        // 创建播客...

        $job = (new ProcessPodcast($podcast))->onQueue(&#39;processing&#39;);

        dispatch($job);
    }}
ログイン後にコピー
ログイン後にコピー

Redis

🎜 redis キューを使用するには設定ファイル config/database.php で Redis データベース接続を設定する必要があります🎜🎜 Redis キュー接続で Redis クラスターを使用する場合、キュー名にはキー ハッシュ タグが含まれている必要があります。 これは、特定のキューのすべての Redis キーが同じハッシュに配置されるようにするためです: 🎜
<?phpnamespace App\Http\Controllers;use App\Jobs\ProcessPodcast;use Illuminate\Http\Request;use App\Http\Controllers\Controller;class PodcastController extends Controller{
    /**
     * 保存一个新的播客。
     *
     * @param  Request  $request
     * @return Response
     */
    public function store(Request $request)
    {
        // 创建播客...

        $job = (new ProcessPodcast($podcast))->onConnection(&#39;sqs&#39;);

        dispatch($job);
    }}
ログイン後にコピー
ログイン後にコピー

その他のキュー ドライバー依存関係拡張パッケージ

🎜 リスト内のキュー サービスを使用する前にインストールする必要があります 次の依存拡張パッケージ: 🎜

🎜🎜

  • 🎜Amazon SQS: aws/aws-sdk-php ~3.0 🎜
  • 🎜Beanstalkd: pda/pheanstalk ~3.0🎜
  • 🎜Redis: predis/predis ~1.0🎜
🎜🎜🎜🎜🎜🎜

タスクの作成

🎜🎜🎜

タスククラスの生成

🎜アプリケーションでは、キューのタスククラスはすべてデフォルトです。 app/Jobs ディレクトリ。このディレクトリが存在しない場合、make:job 職人コマンドを実行すると、このディレクトリが自動的に作成されます。 次のアーティザン コマンドを使用して、新しいキュー タスクを生成できます: 🎜
$job = (new ProcessPodcast($podcast))
                ->onConnection(&#39;sqs&#39;)
                ->onQueue(&#39;processing&#39;);
ログイン後にコピー
ログイン後にコピー
🎜 生成されたクラスは IlluminateContractsQueueShouldQueue インターフェイスを実装します。これは、タスクが同期的に実行されるのではなく、キューにプッシュされることを意味します。 🎜🎜🎜🎜

タスク クラスの構造

🎜 一般に、タスク クラスの構造には、キューがこのタスクを呼び出すために使用する handle メソッドのみが含まれています。この例では、ポッドキャスト公開サービスを管理し、アップロードされたポッドキャスト ファイルを公開前に処理する必要があると仮定します。 🎜
php artisan queue:work --tries=3
ログイン後にコピー
ログイン後にコピー
🎜 この例では、タスク クラスのコンストラクターを An に直接使用していることに注意してください。雄弁なモデルが渡されます。タスク クラスで SerializesModels を参照したため、タスクの処理時に Eloquent モデルを適切にシリアル化および逆シリアル化できます。キュー タスク クラスがコンストラクターで Eloquent モデルを受け取る場合、そのモデルを認識するプロパティのみがキューにシリアル化されます。タスクが実際に実行されると、キュー システムはデータベースから完全なモデルを自動的に取得します。このプロセス全体はアプリケーションに対して完全に透過的であるため、完全な Eloquent パターン インスタンスのシリアル化に伴う問題の一部が回避されます。 🎜

在队列处理任务时,会调用 handle 方法,而这里我们也可以通过 handle 方法的参数类型提示,让 Laravel 的 服务容器 自动注入依赖对象。

{note} 像图片内容这种二进制数据, 在放入队列任务之前必须使用 base64_encode 方法转换一下。 否则,当这项任务放置到队列中时,可能无法正确序列化为 JSON。


分发任务

你写好任务类后,就能通过 dispatch 辅助函数来分发它了。唯一需要传递给 dispatch 的参数是这个任务类的实例:

<?phpnamespace App\Http\Controllers;use App\Jobs\ProcessPodcast;use Illuminate\Http\Request;use App\Http\Controllers\Controller;class PodcastController extends Controller{
    /**
     * 保存播客。
     *
     * @param  Request  $request
     * @return Response
     */
    public function store(Request $request)
    {
        // 创建播客...

        dispatch(new ProcessPodcast($podcast));
    }}
ログイン後にコピー
ログイン後にコピー

{tip} dispatch 提供了一种简捷、全局可用的函数,它也非常容易测试。查看下 Laravel 测试文档 来了解更多。


延迟分发

如果你想延迟执行一个队列中的任务,你可以用任务实例的 delay 方法。 这个方法是 Illuminate\Bus\Queueable trait 提供的,而这个 trait 在所有自动生成的任务类中都是默认加载了的。对于延迟任务我们可以举个例子,比如指定一个被分发10分钟后才执行的任务:

<?phpnamespace App\Http\Controllers;use Carbon\Carbon;use App\Jobs\ProcessPodcast;use Illuminate\Http\Request;use App\Http\Controllers\Controller;class PodcastController extends Controller{
    /**
     * 保存一个新的播客。
     *
     * @param  Request  $request
     * @return Response
     */
    public function store(Request $request)
    {
        // 创建播客...

        $job = (new ProcessPodcast($podcast))
                    ->delay(Carbon::now()->addMinutes(10));

        dispatch($job);
    }}
ログイン後にコピー
ログイン後にコピー

{note} Amazon SQS 队列服务最大延迟 15 分钟。


自定义队列 & 连接

分发任务到指定队列

通过推送任务到不同的队列,你可以给队列任务分类,甚至可以控制给不同的队列分配多少任务。记住,这个并不是要推送任务到队列配置文件中不同的 「connections」 里,而是推送到一个连接中不同的队列里。要指定队列的话,就调用任务实例的 onQueue 方法:

<?phpnamespace App\Http\Controllers;use App\Jobs\ProcessPodcast;use Illuminate\Http\Request;use App\Http\Controllers\Controller;class PodcastController extends Controller{
    /**
     * 保存一个新的播客。
     *
     * @param  Request  $request
     * @return Response
     */
    public function store(Request $request)
    {
        // 创建播客...

        $job = (new ProcessPodcast($podcast))->onQueue(&#39;processing&#39;);

        dispatch($job);
    }}
ログイン後にコピー
ログイン後にコピー

分发任务到指定连接

如果你使用了多个队列连接,你可以把任务推到指定连接。要指定连接的话,你可以调用任务实例的 onConnection 方法:

<?phpnamespace App\Http\Controllers;use App\Jobs\ProcessPodcast;use Illuminate\Http\Request;use App\Http\Controllers\Controller;class PodcastController extends Controller{
    /**
     * 保存一个新的播客。
     *
     * @param  Request  $request
     * @return Response
     */
    public function store(Request $request)
    {
        // 创建播客...

        $job = (new ProcessPodcast($podcast))->onConnection(&#39;sqs&#39;);

        dispatch($job);
    }}
ログイン後にコピー
ログイン後にコピー

当然,你可以链式调用 onConnectiononQueue 来同时指定任务的连接和队列:

$job = (new ProcessPodcast($podcast))
                ->onConnection(&#39;sqs&#39;)
                ->onQueue(&#39;processing&#39;);
ログイン後にコピー
ログイン後にコピー


指定任务最大尝试次数 / 超时值

最大尝试次数

在一项任务中指定最大的尝试次数可以尝试通过 Artisan 命令行 --tries 来设置:

php artisan queue:work --tries=3
ログイン後にコピー
ログイン後にコピー

但是,你可以采取更为精致的方法来完成这项工作比如说在任务类中定义最大尝试次数。如果在类和命令行中都定义了最大尝试次数, Laravel 会优先执行任务类中的值:

<?phpnamespace App\Jobs;class ProcessPodcast implements ShouldQueue{
    /**
     * 任务最大尝试次数
     *
     * @var int
     */
    public $tries = 5;}
ログイン後にコピー

超时

同样的,任务可以运行的最大秒数可以使用 Artisan 命令行上的 --timeout 开关指定:

php artisan queue:work --timeout=30
ログイン後にコピー

然而,你也可以在任务类中定义一个变量来设置可运行的最大描述,如果在类和命令行中都定义了最大尝试次数, Laravel 会优先执行任务类中的值:

<?phpnamespace App\Jobs;class ProcessPodcast implements ShouldQueue{
    /**
     * 任务运行的超时时间。
     *
     * @var int
     */
    public $timeout = 120;}
ログイン後にコピー


错误处理

如果任务运行的时候抛出异常,这个任务就自动被释放回队列,这样它就能被再重新运行了。如果继续抛出异常,这个任务会继续被释放回队列,直到重试次数达到你应用允许的最多次数。这个最多次数是在调用 queue:work Artisan 命令的时候通过 --tries 参数来定义的。更多队列处理器的信息可以 在下面看到 。


运行队列处理器

Laravel 包含一个队列处理器,当新任务被推到队列中时它能处理这些任务。你可以通过 queue:work Artisan 命令来运行处理器。要注意,一旦 queue:work 命令开始,它将一直运行,直到你手动停止或者你关闭控制台:

php artisan queue:work
ログイン後にコピー

{tip} 要让 queue:work 进程永久在后台运行,你应该使用进程监控工具,比如 Supervisor 来保证队列处理器没有停止运行。

一定要记得,队列处理器是长时间运行的进程,并在内存里保存着已经启动的应用状态。这样的结果就是,处理器运行后如果你修改代码那这些改变是不会应用到处理器中的。所以在你重新部署过程中,一定要 重启队列处理器 。

指定连接 & 队列

你可以指定队列处理器所使用的连接。你在 config/queue.php 配置文件里定义了多个连接,而你传递给 work 命令的连接名字要至少跟它们其中一个是一致的:

php artisan queue:work redis
ログイン後にコピー

你可以自定义队列处理器,方式是处理给定连接的特定队列。举例来说,如果你所有的邮件都是在 redis 连接中的 emails 队列中处理的,你就能通过以下命令启动一个只处理那个特定队列的队列处理器了:

php artisan queue:work redis --queue=emails
ログイン後にコピー

资源注意事项

守护程序队列不会在处理每个作业之前 「重新启动」 框架。 因此,在每个任务完成后,您应该释放任何占用过大的资源。例如,如果你使用GD库进行图像处理,你应该在完成后用 imagedestroy 释放内存。


队列优先级

有时候你希望设置处理队列的优先级。比如在 config/queue.php 里你可能设置了 redis 连接中的默认队列优先级为 low,但是你可能偶尔希望把一个任务推到 high 优先级的队列中,像这样:

dispatch((new Job)->onQueue(&#39;high&#39;));
ログイン後にコピー

要验证 high 队列中的任务都是在 low 队列中的任务之前处理的,你要启动一个队列处理器,传递给它队列名字的列表并以英文逗号,间隔:

php artisan queue:work --queue=high,low
ログイン後にコピー


队列处理器 & 部署

因为队列处理器都是 long-lived 进程,如果代码改变而队列处理器没有重启,他们是不能应用新代码的。所以最简单的方式就是重新部署过程中要重启队列处理器。你可以很优雅地只输入 queue:restart 来重启所有队列处理器。

php artisan queue:restart
ログイン後にコピー

这个命令将会告诉所有队列处理器在执行完当前任务后结束进程,这样才不会有任务丢失。因为队列处理器在执行 queue:restart 命令时对结束进程,你应该运行一个进程管理器,比如 Supervisor 来自动重新启动队列处理器。


任务过期 & 超时

任务过期

config/queue.php 配置文件里,每一个队列连接都定义了一个 retry_after 选项。这个选项指定了任务最多处理多少秒后就被当做失败重试了。比如说,如果这个选项设置为 90,那么当这个任务持续执行了 90 秒而没有被删除,那么它将被释放回队列。通常情况下,你应该把 retry_after 设置为最长耗时的任务所对应的时间。

{note} 唯一没有 retry_after 选项的连接是 Amazon SQS。当用 Amazon SQS 时,你必须通过 Amazon 命令行来配置这个重试阈值。

队列处理器超时

queue:work Artisan 命令对外有一个 --timeout 选项。这个选项指定了 Laravel 队列处理器最多执行多长时间后就应该被关闭掉。有时候一个队列的子进程会因为很多原因僵死,比如一个外部的 HTTP 请求没有响应。这个 --timeout 选项会移除超出指定事件限制的僵死进程。

php artisan queue:work --timeout=60
ログイン後にコピー

retry_after 配置选项和 --timeout 命令行选项是不一样的,但是可以同时工作来保证任务不会丢失并且不会重复执行。

{note} --timeout 应该永远都要比 retry_after 短至少几秒钟的时间。这样就能保证任务进程总能在失败重试前就被杀死了。如果你的 --timeout 选项大于 retry_after 配置选项,你的任务可能被执行两次。

队列进程睡眠时间

当队列需要处理任务时,进程将继续处理任务,它们之间没有延迟。 但是,如果没有新的工作可用,sleep 参数决定了工作进程将「睡眠」多长时间:

php artisan queue:work --sleep=3
ログイン後にコピー


Supervisor 配置

安装 Supervisor

Supervisor 是一个 Linux 操作系统上的进程监控软件,它会在 queue:listenqueue:work 命令发生失败后自动重启它们。要在 Ubuntu 安装 Supervisor,可以用以下命令:

sudo apt-get install supervisor
ログイン後にコピー

{tip} 如果自己手动配置 Supervisor 听起来有点难以应付,可以考虑使用 Laravel Forge ,它能给你的 Laravel 项目自动安装与配置 Supervisor。

配置 Supervisor

Supervisor 的配置文件一般是放在 /etc/supervisor/conf.d 目录下,在这个目录中你可以创建任意数量的配置文件来要求 Supervisor 怎样监控你的进程。例如我们创建一个 laravel-worker.conf 来启动与监控一个 queue:work 进程:

[program:laravel-worker]process_name=%(program_name)s_%(process_num)02d
command=php /home/forge/app.com/artisan queue:work sqs --sleep=3 --tries=3autostart=trueautorestart=trueuser=forge
numprocs=8redirect_stderr=truestdout_logfile=/home/forge/app.com/worker.log
ログイン後にコピー

这个例子里的 numprocs 命令会要求 Supervisor 运行并监控 8 个 queue:work 进程,并且在它们运行失败后重新启动。当然,你必须更改 command 命令的 queue:work sqs,以显示你所选择的队列驱动。

启动 Supervisor

当这个配置文件被创建后,你需要更新 Supervisor 的配置,并用以下命令来启动该进程:

sudo supervisorctl reread

sudo supervisorctl update

sudo supervisorctl start laravel-worker:*
ログイン後にコピー

更多有关 Supervisor 的设置与使用,请参考 Supervisor 官方文档。


处理失败的任务

有时候你队列中的任务会失败。不要担心,本来事情就不会一帆风顺。 Laravel 内置了一个方便的方式来指定任务重试的最大次数。当任务超出这个重试次数后,它就会被插入到 failed_jobs 数据表里面。要创建 failed_jobs 表的话,你可以用 queue:failed-table 命令:

php artisan queue:failed-table

php artisan migrate
ログイン後にコピー

然后运行队列处理器,在调用 queue:work 命令时你应该通过 --tries 参数指定任务的最大重试次数。如果不指定,任务就会永久重试:

php artisan queue:work redis --tries=3
ログイン後にコピー


清除失败任务

你可以在任务类里直接定义 failed 方法,它能在任务失败时运行任务的清除逻辑。这个地方用来发一条警告给用户或者重置任务执行的操作等再好不过了。导致任务失败的异常信息会被传递到 failed 方法:

<?phpnamespace App\Jobs;use Exception;use App\Podcast;use App\AudioProcessor;use Illuminate\Bus\Queueable;use Illuminate\Queue\SerializesModels;use Illuminate\Queue\InteractsWithQueue;use Illuminate\Contracts\Queue\ShouldQueue;class ProcessPodcast implements ShouldQueue{
    use InteractsWithQueue, Queueable, SerializesModels;

    protected $podcast;

    /**
     * 创建一个新的任务实例。
     *
     * @param  Podcast  $podcast
     * @return void
     */
    public function __construct(Podcast $podcast)
    {
        $this->podcast = $podcast;
    }

    /**
     * 执行任务。
     *
     * @param  AudioProcessor  $processor
     * @return void
     */
    public function handle(AudioProcessor $processor)
    {
        // 处理上传播客...
    }

    /**
     * 要处理的失败任务。
     *
     * @param  Exception  $exception
     * @return void
     */
    public function failed(Exception $exception)
    {
        // 给用户发送失败通知,等等...
    }}
ログイン後にコピー


任务失败事件

如果你想注册一个当队列任务失败时会被调用的事件,则可以用 Queue::failing 方法。这样你就有机会通过这个事件来用 e-mail 或 HipChat 通知你的团队。例如我们可以在 Laravel 内置的 AppServiceProvider 中对这个事件附加一个回调函数:

<?phpnamespace App\Providers;use Illuminate\Support\Facades\Queue;use Illuminate\Queue\Events\JobFailed;use Illuminate\Support\ServiceProvider;class AppServiceProvider extends ServiceProvider{
    /**
     * 启动任意应用程序的服务。
     *
     * @return void
     */
    public function boot()
    {
        Queue::failing(function (JobFailed $event) {
            // $event->connectionName
            // $event->job
            // $event->exception
        });
    }

    /**
     * 注册服务提供者。
     *
     * @return void
     */
    public function register()
    {
        //
    }}
ログイン後にコピー


重试失败任务

要查看你在 failed_jobs 数据表中的所有失败任务,则可以用 queue:failed 这个 Artisan 命令:

php artisan queue:failed
ログイン後にコピー

queue:failed 命令会列出所有任务的 ID、连接、队列以及失败时间,任务 ID 可以被用在重试失败的任务上。例如要重试一个 ID 为 5 的失败任务,其命令如下:

php artisan queue:retry 5
ログイン後にコピー

要重试所有失败的任务,可以使用 queue:retry 并使用 all 作为 ID:

php artisan queue:retry all
ログイン後にコピー

如果你想删除掉一个失败任务,可以用 queue:forget 命令:

php artisan queue:forget 5
ログイン後にコピー

queue:flush 命令可以让你删除所有失败的任务:

php artisan queue:flush
ログイン後にコピー


任务事件

使用队列的 beforeafter 方法,你能指定任务处理前和处理后的回调处理。在这些回调里正是实现额外的日志记录或者增加统计数据的好时机。通常情况下,你应该在 服务容器 中调用这些方法。例如,我们使用 Laravel 中的 AppServiceProvider:

<?phpnamespace App\Providers;use Illuminate\Support\Facades\Queue;use Illuminate\Support\ServiceProvider;use Illuminate\Queue\Events\JobProcessed;use Illuminate\Queue\Events\JobProcessing;class AppServiceProvider extends ServiceProvider{
    /**
     * 启动任意服务。
     *
     * @return void
     */
    public function boot()
    {
        Queue::before(function (JobProcessing $event) {
            // $event->connectionName
            // $event->job
            // $event->job->payload()
        });

        Queue::after(function (JobProcessed $event) {
            // $event->connectionName
            // $event->job
            // $event->job->payload()
        });
    }

    /**
     * 注册服务提供者。
     *
     * @return void
     */
    public function register()
    {
        //
    }}
ログイン後にコピー

队列 facade 中使用 looping 方法,你可以尝试在队列获取任务之前执行指定的回调方法。举个例子,你可以用闭包来回滚之前已失败任务的事务。

Queue::looping(function () {
    while (DB::transactionLevel() > 0) {
        DB::rollBack();
    }});
ログイン後にコピー

相关推荐:

Laravel延迟队列实现之Lua脚本解析

以上がLaravelのキューシステムの紹介の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

このウェブサイトの声明
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。

ホットAIツール

Undresser.AI Undress

Undresser.AI Undress

リアルなヌード写真を作成する AI 搭載アプリ

AI Clothes Remover

AI Clothes Remover

写真から衣服を削除するオンライン AI ツール。

Undress AI Tool

Undress AI Tool

脱衣画像を無料で

Clothoff.io

Clothoff.io

AI衣類リムーバー

Video Face Swap

Video Face Swap

完全無料の AI 顔交換ツールを使用して、あらゆるビデオの顔を簡単に交換できます。

ホットツール

メモ帳++7.3.1

メモ帳++7.3.1

使いやすく無料のコードエディター

SublimeText3 中国語版

SublimeText3 中国語版

中国語版、とても使いやすい

ゼンドスタジオ 13.0.1

ゼンドスタジオ 13.0.1

強力な PHP 統合開発環境

ドリームウィーバー CS6

ドリームウィーバー CS6

ビジュアル Web 開発ツール

SublimeText3 Mac版

SublimeText3 Mac版

神レベルのコード編集ソフト(SublimeText3)

Laravelで電子メールの送信が失敗したときに返品コードを取得する方法は? Laravelで電子メールの送信が失敗したときに返品コードを取得する方法は? Apr 01, 2025 pm 02:45 PM

Laravelの電子メールの送信が失敗したときに戻りコードを取得する方法。 Laravelを使用してアプリケーションを開発する場合、検証コードを送信する必要がある状況に遭遇することがよくあります。そして実際には...

Laravelスケジュールタスクは実行されません:スケジュール:実行コマンドの後にタスクが実行されていない場合はどうすればよいですか? Laravelスケジュールタスクは実行されません:スケジュール:実行コマンドの後にタスクが実行されていない場合はどうすればよいですか? Mar 31, 2025 pm 11:24 PM

LaravelスケジュールタスクRAN RANSPONSIVEトラブルシューティングRALAVELのスケジュールタスクスケジューリングを使用すると、多くの開発者がこの問題に遭遇します。スケジュール:実行...

Laravelでは、検証コードが電子メールで送信できない状況に対処する方法は? Laravelでは、検証コードが電子メールで送信できない状況に対処する方法は? Mar 31, 2025 pm 11:48 PM

Laravelの電子メールの検証コードの送信の障害を処理する方法は、Laravelを使用することです...

DCAT管理者にデータを追加するためにクリックのカスタムテーブル関数を実装する方法は? DCAT管理者にデータを追加するためにクリックのカスタムテーブル関数を実装する方法は? Apr 01, 2025 am 07:09 AM

DCATを使用するときにDCATADMIN(Laravel-Admin)にデータを追加するためにカスタムクリックのテーブル関数を実装する方法...

Laravel - ダンプサーバー Laravel - ダンプサーバー Aug 27, 2024 am 10:51 AM

Laravel - ダンプサーバー - Laravel ダンプサーバーには、Laravel 5.7 のバージョンが付属しています。以前のバージョンにはダンプ サーバーが含まれていません。ダンプサーバーはlaravel/laravelコンポーザーファイルの開発依存関係になります。

Laravel Redis接続共有:選択方法が他の接続に影響するのはなぜですか? Laravel Redis接続共有:選択方法が他の接続に影響するのはなぜですか? Apr 01, 2025 am 07:45 AM

Laravel FrameworkでRedis接続の共有の影響とLaravelフレームワークとRedisを使用する際のメソッドを選択すると、開発者は問題に遭遇する可能性があります。

Laravel Multi-Tenant Extension Stancl/Tenancy:テナントデータベース接続のホストアドレスをカスタマイズする方法は? Laravel Multi-Tenant Extension Stancl/Tenancy:テナントデータベース接続のホストアドレスをカスタマイズする方法は? Apr 01, 2025 am 09:09 AM

Laravel Multi-Tenant拡張機能パッケージStancl/Tenancyのカスタムテナントデータベース接続Laravel Multi-Tenant ExtensionパッケージStancl/Tenancyを使用したマルチテナントアプリケーションを構築する際の...

Laravel - アクション URL Laravel - アクション URL Aug 27, 2024 am 10:51 AM

Laravel - アクション URL - Laravel 5.7 では、「呼び出し可能なアクション URL」と呼ばれる新機能が導入されています。この機能は、アクションメソッドで文字列を受け入れるLaravel 5.6の機能に似ています。 Laravel 5.7 で導入された新しい構文の主な目的は、

See all articles