Laravel работник не пытается выполнить задание, а скорее удаляет его - PullRequest
2 голосов
/ 06 апреля 2020

laravel 5.4
php 7.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 добавляется новая строка. Затем для работы назначается Laravel Worker , тогда обновляются столбцы 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'] ?? ''));
    }
}

Вот Log

[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 se c. работник удаляет задание, а не пытается его .

1 Ответ

2 голосов
/ 14 апреля 2020

Ваша работа делает запрос скручивания, но не обрабатывает ошибки и не проверяет этот вызов. По какой-то причине запрос может быть неудачным, но эта работа никогда не сообщит вам. Особенно сейчас, когда есть необъяснимая проблема, имеет смысл выполнить некоторую базовую c проверку ошибок запроса и ответа.

Вы можете проверить несколько вещей. Вероятно, нет необходимости делать все это, как только вы решите эту конкретную проблему, но вам, вероятно, следует использовать хотя бы один из них, чтобы следить за этим вызовом.

  • Использовать curl_error(), чтобы проверить, сработал ли вызов;

  • Используйте curl_getinfo(), чтобы показать вам детали сетевого запроса и ответа. Это даст вам много информации, включая http_response, вы можете проверить, что это было 200 или что вы ожидаете;

  • Если удаленный сервер отвечает каким-либо сообщением - предположительно это это потому что вы json_decode() это - войдите. Если в ответе есть какой-то элемент успеха / неудачи, протестируйте его, убедитесь, что он соответствует ожидаемому вами;

Например (как уже упоминалось, вы обычно не выполняете все эти , просто выберите, который подходит вашей ситуации):

$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']);
}
...