Redis 节流 Laravel 作业 "has been attempted too many times or run too long"

Redis throttling Laravel job "has been attempted too many times or run too long"

我想要使用 Laravel 使用 Redis 队列通过 nexmo 发送短信,但有些作业失败,我不明白为什么。 在我的本地环境中,我每 10 秒发送 1 条短信,所以这是我工作的处理方法:

public function handle()
    { 
        Redis::throttle('throttle:sms')->allow(1)->every(10)->then(function(){
            Log::info($this->notifId." start : ".date('H:m:s'));
            try{
                $before = microtime(true);
                $response = Nexmo::message()->send([
                                'to'   => $this->to,
                                'from' => '16105552344',
                                'text' => $this->message
                            ]);
                $notif = NotificationHistory::find($this->notifId);
                $notif->nexmo_message_id=$response->getMessageId();
                $notif->save();

                $after = microtime(true);
                Log::info(($after-$before)." sec\n");
            }catch(Exeption $e){
                log::warning($e);
            }
        },function($error){
            Log::error($error);
            return $this->release(10);//release job in X second
        });
    }

但是我得到了一些 Illuminate\Contracts\Redis\LimiterTimeoutException 并且当我达到尝试次数限制时最终 MaxAttemptsExceededException

我从 php artisan queue:work --queue=sms --timeout=60 开始我的工人 我这样安排我的工作:

foreach($someEntities as $entitiy) {
            $notif = new NotificationHistory();
            $notif->notifiable()->associate($entity);
            $notif->message=$entity->message;
            $notif->status=NotificationHistory::$statusList[-1];
            $notif->save();
            dispatch(new SendSMS($entity->message."_".$notif->id,$entity->phone,$notif->id))->onConnection('redis')->onQueue('sms');
    }

当尝试发送 8 条短信时,前 5 条或 6 条有效,但我发现其他的例外。

编辑 我在没有 nexmo 的情况下得到了同样的错误:

public function handle()
    { 
        Redis::throttle('throttle:sms')->allow(1)->every(10)->then(function(){
            Log::info($this->notifId." startAt : ".date('H:m:s'));
        },function($error){
            Log::error($error);
            return $this->release(10);//release job in X second
        });
    }

问题是“horizon”文件强制尝试 3。

队列工作者实际上并不是每 10 秒 运行 一次,如果队列中有东西,它会连续 运行。 当它处理一个作业时,如果它已经在过去 10 秒内处理了一个作业,它将从队列中删除它的当前作业并在 X 秒后将其放回(在 release(x) 中定义),生成一个 LimiterTimeoutException并增加它的尝试价值。 所以当 worker 尝试同一个工作达到 3 次时,它就会失败。