使用queue:work后,Laravel作业中的SoapClient“无法连接到主机”一段时间

问题描述 投票:1回答:1

我正在使用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毫秒,那么也不错,因此Web服务为900毫秒,处理队列仅为100毫秒。对于每个请求,我们平均有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环境,如What is the difference queue:work and queue:listen所述,这种情况不会发生,显然是由于环境的重新加载造成的。

使用queue:listen,性能下降得非常显着,从每秒6条消息传递到3条,这意味着每次调用所需的平均值为150毫秒,总计达450毫秒,排队过程需要剩余的550毫秒,即大约180毫秒每次通话,比以前多11次。

这完全有道理,但我想知道是否有办法用SoapClient来防止这个错误。

php laravel soap soap-client laravel-queue
1个回答
0
投票

在经过多次尝试后,我偶然发现了一种阻止此行为发生的解决方案。

问题是关于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
]);

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

这可能不是超级优化的,但在我长时间运行的脚本上下文中可以防止我遇到的奇怪错误,并且长时间(小时)测试这个错误永远不会回来

© www.soinside.com 2019 - 2024. All rights reserved.