Php SoapClient 在第一次连接时非常慢

Php SoapClient is very slow on first connection

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

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

因为第一次初始化需要几分钟,我的 nginx 服务器 returns 1 分钟后出现 504 网关 time-out 错误。

Web 服务 URL 使用 HTTPS,我们使用 SSL 证书。我们还必须使用登录名和密码进行身份验证。我使用了一个 session cookie,可以使用 8 小时,我在 HTTP 请求 header 中添加了它。我们不使用代理。

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

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

这是我的 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 -------

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

// 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文件并将其放在与我的项目解决问题相同的服务器上。

我在 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]
  ))
));