大量佇列任務總是 MaxAttemptsExceededException,怎麼辦?

waney發表於2019-08-08

一、異常資訊:

在做拉取公眾號粉絲資料的時候,我將任務都放入佇列,一頓操作後遇到

Illuminate\Queue\MaxAttemptsExceededException: App\Jobs\SyncOfficialAccountUserJob has been attempted too many times or run too long. The job may have previously timed out. in /vendor/laravel/framework/src/Illuminate/Queue/Worker.php:599

二、程式思路

以一個15萬粉絲的公眾號舉例,我的做法如下:
透過開放平臺授權推送訊息,觸發事件

App\Listeners\SyncOfficialAccountUser

透過介面 user->list 取得openId 列表,一次拉取呼叫最多拉取10000個,一共要拉取15次;
然後每10000個按每500進行分塊之後扔入佇列等待執行,相當於每10000有20個任務,15萬有300個任務;

$chunks = collect($data['data']['openid'])->chunk('500');
    $chunks->each(function  ($item,  $key)  {
    SyncOfficialAccountUserJob::dispatch(['appId'  =>  $this->authorizerAppid,  'list'  =>  $item->toArray()]);
});

三、相關配置如下:

.env

QUEUE_CONNECTION=redis

config/horizon.php

'waits'  =>  [
    'redis:default' => 60,
],
'trim' => [
    'recent' => 120,
    'failed' => 10080,
    'monitored' => 10080,
],
'fast_termination' => false,
'memory_limit' => 64,
'production' => [
    'supervisor-1' => [
        'connection' => 'redis',
        'queue' => ['default'],
        'balance' => 'simple',
        'processes' => 15,
        'tries' => 3,
    ],
],

四、執行結果

 失敗任務 258個,成功拉取85794個粉絲。
 第一條完成時間:15:04:16,最後一條完成時間:16:26:07

五、換思路

在收到推送觸發事件後將資訊寫入快取,然後用定時任務去快取中取資料,每次少量任務放入佇列處理。
不知道這個可行不,有經驗的朋友請留下你的腳印~~
謝謝了。

本作品採用《CC 協議》,轉載必須註明作者和本文連結

相關文章