Laravelキューテクニック:Fail、RetryまたはDelay

9781 ワード

記事は専門のLaravel開発者コミュニティから転送され、元のリンク:https://learnku.com/laravel/t...
キューjobs、リスナー、またはサブスクリプションサーバを作成してキューにプッシュすると、割り当てられると、キュー・ワークが論理をどのように処理するかを決定するのは、完全に自分で決定すると考え始める可能性があります.
うーん...ジョブ内部からキューワークと対話できないわけではありませんが、通常はやっても必要ありません.
この不思議な騒ぎの出現は「InteractsWithQueue」というtraitのためだ.キュージョブがキューから引き出されている場合、この[CallQueuedListener](https://github.com/laravel/framework/blob/5.8/src/Illuminate/Events/CallQueuedListener.php#L90-L104)InteractsWithQueue traitを使用しているかどうかを確認し、もしそうであれば、フレームワークは最下位の「キューjobs」インスタンスを内部に注入します.
この「タスク」の例は、キュー接続や試行などの情報を含む真のJobクラスをパッケージしたドライバと同様である.
背景
トランスコードJobを例に挙げます.これは、放送オーディオファイルを192 kbps MP 3フォーマットに変換するタスクです.これはフリートランスコードキューで設定されているため、その役割は限られています.
試行回数の確認attempts()は呼び出された最初の方法であり、その名の通り、試行回数を返し、 jobは常にattempt起動を伴う.
このメソッドは、他のメソッドとともに使用することを目的としています....fail()またはrelease()(delay)と同様である.説明を容易にするために、ユーザーに何回目の再試行を通知します.アイドルキューで変換(変換コード)を試みるたびに、将来の変換(変換コード)をキャンセルすることを選択できるように、何回目の再試行中であるかをユーザーに通知します.
podcast = $podcast;
    }
    /**
     *     job.
     *
     * @param \Transcoder\Transcoder $podcast
     * @return void
     */
    public function handle(Transcoder $transcoder)
    {
        //            
        if ($this->attempts() > 1) {
            $this->podcast->publisher->notify(new RetryingPodcastTranscode($this->podcast, $this->attempts());
        }
        $transcoded = $this->transcoder->setFile($event->podcast)
            ->format('mp3')
            ->bitrate(192)
            ->start();
            

        //    podcast   podcast  
        $this->podcast->transcode()->associate($transcoded);
        
        //   podcast      podcast      

        $this->publisher->notify(new PodcastTranscoded($this->podcast));
    }
}

何回目に何かを再試行することをユーザーに伝えます.これは、論理的に事前に失敗したときに役立ち、ユーザー(または開発者)に何か問題があるかをチェックさせることができますが、もちろん多くのことをすることができます.
個人的には、「ジョブ」に失敗した後にこのようにするのが好きです.もし再試行の時間があれば、後で再試行すると言ってください.もちろん、この例は例を挙げるためだけです.
ジョブキューJobの削除
2つ目の方法はdelete()である.予想通り、現在のキューJobをキューから削除できます.キューJobまたはリスナーが様々な理由でキューに並んだ後に処理すべきでない場合、これは便利です.例えば、トランスコードが発生する前にpodcastをアップロードしたパブリッシャーがTOS競合などの理由で停止され、podcastを処理しないことを考慮します.
このコードを前の例で追加します.
podcast = $podcast;
    }
    /**
     *      job.
     *
     * @param \Transcoder\Transcoder $podcast
     * @return void
     */
    public function handle(Transcoder $transcoder)
    {
        //            ,      job
        if ($this->podcast->publisher->isDeactivated()) {
            $this->delete();
        }
        //            
        if ($this->attempts() > 1) {
            $this->podcast->publisher->notify(new RetryingPodcastTranscode($this->podcast, $this->attempts());
        }
        $transcoded = $this->transcoder->setFile($event->podcast)
            ->format('mp3')
            ->bitrate(192)
            ->start();
            
        //    podcast   podcast  
        $this->podcast->transcode()->associate($transcoded);
        
        //   podcast      podcast      
        $this->publisher->notify(new PodcastTranscoded($this->podcast));
    }
}

削除された可能性のあるモデル上のジョブを削除する必要がある場合は、存在しないものの処理を回避するために[$deleteWhenMissingModels](https://laravel.com/docs/5.8/queues#ignoring-missing-models)を設定する必要がある場合があります.
失敗したキューjob
これは、空のreturn文を使用するとJobが正常に完了したとマークされるため、制御者が論理を破壊する必要がある場合に便利です.キューに並んだジョブを強制的に失敗させ、例外を発生させ、プロセッサが可能な場合に後で再試行できるようにします.
これにより、ジョブが失敗した場合にどのような状況でもよりよく制御できます.また、失敗した後にユーザーに通知したり、削除したりするなど、クリーンな操作を実行することができます.
この例では、CDNがオフの場合など、何らかの理由でpodcastをストレージから取得できない場合、ジョブは失敗し、カスタム例外が発生します.
podcast = $podcast;
    }
    /**
     *      job.
     *
     * @param \Transcoder\Transcoder $podcast
     * @return void
     */
    public function handle(Transcoder $transcoder)
    {
        //            ,      job
        if ($this->podcast->publisher->isDeactivated()) {
            $this->delete();
        }
        //  podcast   storage     ,      。
        if ($this->podcast->fileDoesntExists()) {
            $this->fail(new PodcastUnretrievable($this->podcast));
        }
        //            
        if ($this->attempts() > 1) {
            $this->podcast->publisher->notify(new RetryingPodcastTranscode($this->podcast, $this->attempts());
        }
        
        $transcoded = $this->transcoder->setFile($event->podcast)
                ->format('mp3')
                ->bitrate(192)
                ->start();
            
        //    podcast   podcast  
        $this->podcast->transcode()->associate($transcoded);
        
        //   podcast      podcast      
        $this->publisher->notify(new PodcastTranscoded($this->podcast));
    }
}

今、最後の方法に入ります.
キューjobの解放(遅延)
これはtrait性状の最も有用な方法かもしれません.それはあなたが将来このキューjobをさらに推進することができるからです.この方法はキューjobレート制限に用いる.
レート制限に加えて、使用できない場合もありますが、近い将来使用したい場合は、先制的な失敗を避けることができます.
最後の例では、後で使用するために遅延トランスコードを使用します.トランスコーダが大量に使用されている場合は、負荷が低下するまで5分間遅延トランスコードを使用します.
podcast = $podcast;
    }
    /**
     *     job.
     *
     * @param \Transcoder\Transcoder $podcast
     * @return void
     */
    public function handle(Transcoder $transcoder)
    {
        //            ,      job
        if ($this->podcast->publisher->isDeactivated()) {
            $this->delete();
        }
        //   podcast   storage     ,      。
        if ($this->podcast->fileDoesntExists()) {
            $this->fail(new PodcastUnretrievable($this->podcast));
        }
        
        //           ,   
        // t    5  .                    
        //                 。
        if ($transcoder->getLoad()->isHigh()) {
            $delay = 60 * 5;
            $this->podcast->publisher->notify(new TranscoderHighUsage($this->podcast, $delay));
            $this->release($delay);
        }
        //            
        if ($this->attempts() > 1) {
            $this->podcast->publisher->notify(new RetryingPodcastTranscode($this->podcast, $this->attempts());
        }
        
        $transcoded = $this->transcoder->setFile($event->podcast)
                ->format('mp3')
                ->bitrate(192)
                ->start();
            
        //    podcast   podcast  
        $this->podcast->transcode()->associate($transcoded);
        
        //   podcast      podcast      
        $this->publisher->notify(new PodcastTranscoded($this->podcast));
    }
}

例えば、トランスコーダに割り当てられたいくつかのスロットを取得し、トランスコーダスロットが満タンである場合、ジョブを遅延させるなど、いくつかの特殊な方法を用いることができる.並んでいる仕事の中で、あなたができることはこれだけです.行列が楽しい.