Laravel 作业 "cannot connect to host" 中的 SoapClient 在使用 queue:work 一段时间后

SoapClient in a Laravel Job "cannot connect to host" after a while when using queue:work

我正在使用 Laravel 作业来安排 Web 服务调用,单个请求工作正常,这意味着与主机的连接没有问题,也没有任何其他问题,Web 服务通信是好的。

我使用 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 毫秒就不错了 用于 Web 服务,仅 100ms 用于处理队列。对于每个请求,我们平均有 16ms 用于队列处理。

过了一会儿(不到一分钟),情况发生了变化:每次 Web 服务调用都失败,但出现异常

[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 毫秒,排队过程占用了剩余的550ms,也就是每次调用差不多180ms,比之前多了11倍。

这完全有道理,但我想知道是否有办法用 SoapClient.

来防止这个错误

经过多次尝试,我偶然发现了一个解决方案,可以防止这种行为发生。

问题出在 SoapClient keep_alive 指标上。

使用错误的 keep_alive 标志创建 SoapClient

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

您阻止它建立保持连接,因此每次调用都会创建一个全新的网络服务连接。

这可能不是超级优化,但在我的长脚本上下文中,运行 防止了我遇到的奇怪错误,并且测试了很长时间(几个小时)错误再也没有回来