【问题标题】:Php SoapClient is very slow on first connectionPhp SoapClient 在第一次连接时很慢
【发布时间】:2019-10-01 08:35:58
【问题描述】:

我使用 php SoapClient 调用存储在我们内部服务器上的 M3 (Movex) 网络服务。我进行调用的 Symfony 3.4 项目位于另一个内部 linux 服务器上。

我注意到,soap 客户端的初始化非常缓慢(2-3 分钟),长时间不使用它(几个小时)后完成。例如,它发生在早上,当我在一天中第一次测试我的项目时。但是我对几分钟后完成的每次初始化和调用都没有问题(在 500 毫秒内响应)。

由于第一次初始化需要几分钟,我的 nginx 服务器在 1 分钟后返回 504 网关超时错误。

Web 服务 URL 采用 HTTPS,我们使用 SSL 证书。我们还必须使用登录名和密码进行身份验证。我使用了一个 8 小时可用的会话 cookie,我将它添加到 HTTP 请求标头中。我们不使用代理。

我认为这是一个缓存问题。当我使用 SoapUI 时,我没有遇到问题,webservice 响应非常快。

这是我的php.ini中soap扩展的配置:

这是我的肥皂客户端初始化:

$client = new SoapClient("https://my-domain.com:55080/my-webservice?wsdl", array(
  'login'     => $login,
  'password'  => $pwd,
  'trace'     => true,
  'exceptions' => true,
  'stream_context' => stream_context_create(array(
    'http' => ['header' => 'cookie: ' . $cookie]
  ))
));

我尝试在选项中添加'cache_wsdl' => WSDL_CACHE_MEMORY,但更糟糕的是,每次我使用它时,它都很慢。

这里是查看问题所在的日志(查看第 3 行和第 4 行 -> 2 分钟):

01/10/19 09:58:06 ------- Get Customer -------
01/10/19 09:58:06 - Cookie exists -> send it in the request
01/10/19 09:58:06 - BEGIN Init soap client
01/10/19 10:00:07 - END Init soap client
01/10/19 10:00:07 - BEGIN client->GetCustomerData
01/10/19 10:00:07 - END client->GetCustomerData
01/10/19 10:00:07 ------- END Get Customer -------

当我在几分钟后再次测试时(没问题,在同一秒内完成):

01/10/19 10:03:52 ------- Get Customer -------
01/10/19 10:03:52 - Cookie exists -> send it in the request
01/10/19 10:03:52 - BEGIN Init soap client
01/10/19 10:03:52 - END Init soap client
01/10/19 10:03:52 - BEGIN client->GetCustomerData
01/10/19 10:03:52 - END client->GetCustomerData
01/10/19 10:03:52 ------- END Get Customer -------

【问题讨论】:

  • 您能否检查您的 WSDL 文件中是否有对 XSD 定义/XSD 文件的引用,这些文件是 W3C 服务器上的主机?由于流量过多,w3c 对定义设置了延迟:w3.org/blog/systeam/2008/02/08/w3c_s_excessive_dtd_traffic 您可以下载这些定义并将它们托管在您自己的服务器上。当您这样做时,您也必须重写 wsdl 文件并将其托管在您自己的服务器上。另一种解决方案可能是在选项中使用不同的用户代理设置您的肥皂客户端。只需将您的客户端伪装成浏览器,延迟就消失了。可能是原因之一。
  • 感谢您的回答。你的意思是那种网址xmlns:xsd="http://www.w3.org/2001/XMLSchema"?我也有这个xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/" 和很多来自http://schemas.lawson.com/... 的网址,但是这个命名空间不起作用。
  • @Marcel 我对您的第二个解决方案感兴趣。你能写信给我,我怎样才能把我的客户伪装成浏览器?

标签: php caching soap wsdl soap-client


【解决方案1】:

作为对您在 cmets 中的问题的回答,您可以尝试将您的肥皂客户端伪装成浏览器。这可能是一个可能的解决方案。没有保证,这是唯一的解决方案。 ;)

// options
$wsdl = 'https://your.service.url.here?wsdl';

$options = [
    'trace' => true,
    'exceptions' => true,
    'cache_wsdl' => WSDL_CACHE_NONE,
    'connection_timeout' => 30,
    'user_agent' => 'Mozilla/1.0N (Windows)',
];

try {
    $client = new SoapClient($wsdl, $options);
    // more logic here
} catch (SoapFault $e) {
    var_dump($e);
}

【讨论】:

  • 好的,谢谢,我去测试一下。但我没有添加WSDL_CACHE_NONE,因为它会进一步减慢我的请求速度。
  • 这只是一个复制和粘贴问题。 ;) 你可以试试WSDL_CACHE_DISKWSDL_CACHE_MEMORYWSDL_CACHE_BOTH 选项。
  • 不幸的是它没有解决我的问题,使用自定义用户代理的初始化仍然很慢。
【解决方案2】:

下载 wsdl 文件并将其放在与我的项目解决问题相同的服务器上。

soap 客户端的初始化过程中没有延迟。我也禁用了缓存。现在完美运行。

$client = new SoapClient("https://". $_SERVER['HTTP_HOST'] ."/path-to/file.xml", array(
  'login'      => $login,
  'password'   => $pwd,
  'trace'      => true,
  'exceptions' => true,
  'cache_wsdl' => WSDL_CACHE_NONE,
  'stream_context' => stream_context_create(array(
    'http' => ['header' => 'cookie: ' . $cookie]
  ))
));

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-12-23
    • 1970-01-01
    • 2015-05-28
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多