一、異常資訊:
在做拉取公眾號粉絲資料的時候,我將任務都放入佇列,一頓操作後遇到
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 協議》,轉載必須註明作者和本文連結