Laravel 工作人员没有尝试工作而是删除了它

Laravel worker not attempting the job but rather deleting it

laravel 5.4
php7.1.32
主管 3.3.1
(我知道...我知道。公司落后运行 3年)

config/queue.php

'database' => [
    'driver' => 'database',
    'connection' => 'queue', // means in config/database.php I have to setup a new connection
    'table' => 'jobs',
    'queue' => 'default',
    'retry_after' => 90,
],

主管配置

[program:laravel-worker]
process_name=%(program_name)s_%(process_num)02d
command=php /var/www/html/project/artisan queue:work
autostart=true
autorestart=true
user=root
numprocs=1
redirect_stderr=true
stdout_logfile=/var/www/html/project/storage/logs/supervisord.log


SCENARIO:调度队列时,新行会添加到 jobs table。然后 Laravel 工人 被分配到一个工作,那是 reserved_at & 尝试 列已更新。作业完成后,行(作业)将被删除。

现在,由于一些神秘的原因,有时工作会无缝运行 & 有时工作在那里,但没有分配给它的工人,并且在一瞬间该工作被删除。刚才发生了什么?此外,这是间歇性的,很难跟踪哪些作业实际尝试过,后来被删除或刚刚被这个问题删除。

我已经摸不着头脑至少一个星期了,请指导我。


编辑
- php artisan queue:restart 广播,主管更新正常运行时间但问题没有改善。
- 后来,我删除了主管并尝试以手动方式 php artisan queue:work 甚至 删除了工作而不是尝试它 (failed_jobs 中没有插入新数据要么)。


编辑 (2) - 日志
这是调度作业

的函数
public static function sendVoiceCall($instituteSmsSettings, $announcementId, $postUrl, $mobileNumbers)
    {
        Log::debug('Job dispatched');
        dispatch(new SendVoiceCall($instituteSmsSettings, $announcementId, $postUrl, $mobileNumbers));
    }

这是工作

<?php

namespace App\Jobs;

use Illuminate\Bus\Queueable;
use Illuminate\Queue\SerializesModels;
use Illuminate\Queue\InteractsWithQueue;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Foundation\Bus\Dispatchable;
use Illuminate\Support\Facades\Log;

class SendVoiceCall implements ShouldQueue
{
    use Dispatchable, InteractsWithQueue, Queueable, SerializesModels;

    public $tries = 3;
    protected $ARR_POST_DATA = array();
    protected $postUrl = '';

    public function __construct($instituteSmsSettings, $announcementId, $postUrl, $mobileNumbers)
    {
        $this->ARR_POST_DATA['username'] = $instituteSmsSettings->username;
        $this->ARR_POST_DATA['token'] = $instituteSmsSettings->token;
        $this->ARR_POST_DATA['announcement_id'] = $announcementId;
        $this->ARR_POST_DATA['plan_id'] = $instituteSmsSettings->plan_id;
        $this->ARR_POST_DATA['caller_id'] = $instituteSmsSettings->caller_id;
        $this->ARR_POST_DATA['contact_numbers'] = $mobileNumbers;
        $this->postUrl = $postUrl;
    }

    public function handle()
    {
        Log::debug('Job started');
        $curl = curl_init();
        curl_setopt($curl, CURLOPT_URL, $this->postUrl);
        curl_setopt($curl, CURLOPT_POST, 1);
        curl_setopt($curl, CURLOPT_POSTFIELDS, http_build_query($this->ARR_POST_DATA));
        curl_setopt($curl, CURLOPT_RETURNTRANSFER, TRUE);

        $sendCallResponse = curl_exec($curl);
        $curlResponse = json_decode($sendCallResponse, true);
        curl_close($curl);

        Log::info('Queue complete. Announcement Id: ' . ($this->ARR_POST_DATA['announcement_id'] ?? ''));
    }
}

这是 日志

[2020-04-13 10:17:49] production.DEBUG: Job dispatched  
[2020-04-13 10:17:50] production.DEBUG: Job started  
[2020-04-13 10:17:50] production.INFO: Queue complete. Announcement Id: 203691 

如您所见,队列同时开始和结束(应该有 2-3 秒的差异。工作人员正在删除作业而不是尝试它.

您的作业正在发出 curl 请求,但没有对该调用进行错误处理或检查。该请求可能由于某种原因而失败,但这项工作永远不会告诉您。特别是现在,当出现无法解释的问题时,对请求和响应进行一些基本的错误检查是有意义的。

您可以检查几件事。解决了这个特定问题后,可能不需要执行所有这些操作,但您可能应该至少使用其中一个来密切关注此调用。

  • 使用curl_error()检查通话是否有效;

  • 使用curl_getinfo()向您显示网络请求和响应的详细信息。这将为您提供很多信息,包括 http_response,您可以测试它是 200 或您期望的任何内容;

  • 如果远程服务器响应某些消息 - 可能是因为您正在 json_decode()ing 它 - 记录它。如果响应中有某种 success/failure 元素,请对其进行测试,确保它符合您的预期;

例如(如前所述,您通常不会做所有这些,只需选择适合您的情况):

$curl = curl_init();
// ... your code

// Get request info as an array
$info = curl_getinfo($curl);

$sendCallResponse = curl_exec($curl);
curl_close($curl);

// Log the actual response from the remote server
Log:info('Curl response: ' . $sendCallResponse);

// Log extensive info about the request/response, good when troubleshooting
Log:info('Curl info: ' . print_r($info, true));

// Maybe check the http response code
if ($info['http_code'] !== 200) {
    // handle an error, send a notification, etc
    Log:info('Whoah, remote server responded with ' . $info['http_code']);
}

// Maybe check if curl returned an error
if ($sendCallResponse === false) {
    // handle an error, send a notification, etc
    Log:info('Oh noes, curl error! ' . curl_error($curl));
}

// Maybe test the actual response, if there is something testable in it, 
// say a "status":
if ($curlResponse['status'] !== 'OK') {
    // handle an error, send a notification, etc
    Log:info('Remote returned status ' . $curlResponse['status']);
}