我正在使用 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 队列:work --queue=soapQueue
正如预期的那样,请求被假脱机和处理,速度相当不错,每秒大约 6 个请求,如果您考虑到每个 SOAP 调用大约需要 150 毫秒,那么就不错了,所以 900 毫秒对于 Web 服务,处理队列仅需100ms。对于每个请求,我们的队列处理时间平均为 16 毫秒。
过了一会儿(不到一分钟),事情发生了变化:每个 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 毫秒,排队过程需要剩余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
]);
您阻止它建立保持事件连接,因此每次调用都会创建与 Web 服务的全新连接。
这可能不是 super 优化的,但是在我长时间运行的脚本上下文中可以防止出现奇怪的错误,并且测试了很长一段时间(几个小时)错误再也没有回来
关于php - 使用队列 :work 一段时间后,Laravel 作业 "cannot connect to host"中的 SoapClient,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55415307/