php - 使用队列 :work 一段时间后,Laravel 作业 "cannot connect to host"中的 SoapClient

标签 php laravel soap soap-client laravel-queue

我正在使用 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/

相关文章:

php - Laravel Form-Model Binding 多选默认值

laravel - 如何使用 Eloquent 在 Laravel 中开始查询?

java - 在 Spring WS 中返回带有自定义错误代码和消息的 SOAP 错误对象

PHP:exiftool 的基本用法

php - 无法实时从redis读取

php - 使用 cURL 执行 SOAP

java - 添加wsse :UsernameToken in soap header

php - 为什么 MySQL 在执行查询获取每月计数时返回错误?

php - Drupal SAML 登录重定向不起作用

php - 将 PHP 文件更新到服务器未反射(reflect)其在应用程序中的功能