SoapClient в задании Laravel "не может подключиться к хосту" через некоторое время при использовании очереди: работа - PullRequest
1 голос
/ 29 марта 2019

Я использую задание Laravel для планирования вызова веб-службы, и один запрос просто работает нормально, то есть нет проблем с подключением к хосту, как и с любым другим, связь с веб-службой в порядке.

Я использую инициализацию WSDL SoapClient, что-то вроде

$soapClient = new \SoapClient($wsdl,[
        'trace' => 1,
        'features' => SOAP_SINGLE_ELEMENT_ARRAYS,
        'keep_alive' => true,
        'compression' => SOAP_COMPRESSION_ACCEPT | SOAP_COMPRESSION_GZIP,
        'cache_wsdl' => WSDL_CACHE_MEMORY
]);

Как только очередь начала получать серьезный трафик, я включил очередь спулинга с помощью

php artisan queue:work --queue=soapQueue

Как и ожидалось, запросы помещаются в очередь и обрабатываются с довольно приличной скоростью, более или менее 6 запросов в секунду, что неплохо, если учесть, что каждый вызов SOAP занимает более или менее 150 мс, поэтому 900 мс для веб-службы и только 100мс для обработки очереди.Для каждого запроса у нас есть в среднем 16 мс для обработки очереди.

Через некоторое время (менее минуты) что-то меняется: каждый вызов веб-службы завершается неудачей, за исключением

[2019-03-29 09:50:29] local.ERROR: Could not connect to host  
[2019-03-29 09:50:29] local.ERROR: #0 [internal function]: SoapClient->__doRequest('<?xml version="...', 'https://ws.host...', 'PAR_ServiceCall...', 1, 0)

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

Более того, если я использую queue:listen вместо queue:work (это означает, что вы перезагружаете среду Laravel при каждом задании, как описано в В чем разница между очередью: работа и очередь: прослушивание этого не происходит, очевидно, из-за перезагрузки среды.

При использовании queue:listen производительность значительно снижается, переходя от 6 сообщений в секунду к 3, что означает, что при одинаковом среднем 150 мс требуетсядля каждого вызова, суммируя до 450 мс , процесс очереди занимает оставшиеся 550 мс , то есть более или менее 180 мс для каждого вызова, в 11 раз больше, чем раньше.

Это прекрасно имеет смысл, но мне было интересно, есть ли способ предотвратить эту ошибку с помощью SoapClient.

1 Ответ

0 голосов
/ 03 апреля 2019

После МНОЖЕГО попыток я наткнулся на решение, которое предотвратило такое поведение.

Проблема была в индикаторе SoapClient keep_alive.

Создание SoapClient с ложным флагом keep_alive

$soapClient = new \SoapClient($wsdl,[
    'trace' => 1,
    'features' => SOAP_SINGLE_ELEMENT_ARRAYS,
    'keep_alive' => false,
    'compression' => SOAP_COMPRESSION_ACCEPT | SOAP_COMPRESSION_GZIP,
    'cache_wsdl' => WSDL_CACHE_MEMORY
]);

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

Это не может быть супероптимизировано, но в моем долгосрочном контексте сценария предотвращает странную ошибку, которая у меня была, и проверяя ее в течение длительного времени (часы), ошибка никогда не возвращалась

...