【问题标题】:Consuming SOAP and REST WebServices at the same time in PHP在 PHP 中同时使用 SOAP 和 REST WebServices
【发布时间】:2015-07-17 14:21:18
【问题描述】:

我的目标是使用各种 Web 服务,然后合并结果。

我使用PHP cURL 执行此操作,但随着 Web 服务数量的增加,我的服务变慢了,因为该进程正在等待响应,然后向下一个 Web 服务发出请求。

我使用curl_multi 解决了这个问题,一切正常。

现在,我遇到了一个新问题,因为我有新的 Web 服务要添加到使用 Soap Protocol 的服务中,并且我不能再同时请求,因为我不使用 cURL 进行 Soap Web 服务,我使用SoapClient

我知道我可以使用 soap 指令生成 XML,然后使用 cURL 发送它,但在我看来这是一个不好的做法。

简而言之,有什么方法可以同时使用 REST 和 SOAP Web 服务?

【问题讨论】:

    标签: php web-services curl soap


    【解决方案1】:

    我会首先尝试一个统一的异步guzzle 设置,就像其他人所说的那样。如果这不起作用,我建议 not 使用进程分叉或多线程。两者都不容易使用或维护。例如,mixing guzzle and threads 需要特别注意。

    我不知道您的应用程序的结构,但这可能是队列的一个好例子。为每个 API 调用将消息放入队列,并让多个 PHP daemons 从队列中读出并发出实际请求。可以将代码组织为根据协议或端点使用 curl 或 SoapClient,而不是尝试将它们组合起来。只需启动尽可能多的守护进程,即可并行发出请求。这避免了线程或进程管理的所有复杂性,并且可以轻松扩展。

    当我使用这种架构时,我还会跟踪键值存储或数据库中的“信号量”。使用要进行的 API 调用计数来启动信号量。当每个都完成时,计数会减少。每个进程都会检查计数何时达到零,然后您就知道所有工作都已完成。这仅在有后续任务时才真正需要,例如从所有 API 结果中计算某些内容或更新记录以让用户知道工作已完成。

    现在这种设置听起来比进程分叉或多线程更复杂,但每个组件都易于测试,并且可以跨服务器扩展。

    我整理了一个PHP library,它有助于构建我所描述的架构。它是允许同步和异步进程混合的基本流水线。异步工作由队列和信号量处理。需要按顺序发生的 API 调用每个都会得到一个 Process 类。可以同时进行的 API 调用进入 MultiProcess 类。 ProcessList 设置管道。

    【讨论】:

      【解决方案2】:

      是的,你可以。

      使用 HTTP 客户端(例如:guzzle、httpful)他们中的大多数都关注PSR7,在此之前您将有一个合同。最重要的是,他们有大量的 SOAP 和 REST 插件。

      EX:如果你选择 guzzle 作为你的 HTTP 客户端,它有插件 SOAP。你知道 REST 就是调用一个服务,所以你不需要额外的包,只需使用 guzzle 本身。

      **以异步方式(非阻塞)编写您的 API 调用,这将提高性能。一种解决方案是您可以使用promises

      Read more

      【讨论】:

        【解决方案3】:

        它不是 php 擅长的,你可以通过它轻松找到边缘情况下的崩溃错误,但 php 可以执行多线程 - 检查 php pthreadspcntl_fork。 (它们都不能在 php-fpm / mod_php 、 btw 和 pcntl_fork 后面的网络服务器上工作,只能在 unix 系统(linux/bsd)上工作,windows 不能工作)

        但是,您最好切换到主进程 -> 使用 proc_open & co 的工作进程模型。这在 php-fpm 和 mod_php 中都在网络服务器后面工作,并且不依赖于安装的 pthreads,甚至可以在 Windows 上工作,并且如果单个工作人员崩溃,也不会导致其他工作人员崩溃。你也可以放弃使用 php 的 curl_multi 接口(imo 很难做到这一点),并继续使用简单的 curl_exec 和 co 函数。 (这是一个运行多个 ping https://gist.github.com/divinity76/f5e57b0f3d8131d5e884edda6e6506d7 实例的示例 - 但我建议为此使用 php cli,例如 proc_open('php workerProcess.php',...); ,我之前已经成功完成了几次。)

        【讨论】:

          【解决方案4】:

          您可以使用 crontab 运行 cronjob.php 并异步启动其他 php 脚本:

          // cronjob.php
          $files = [
              'soap-client-1.php',
              'soap-client-2.php',
              'soap-client-2.php',
          ];
          
          foreach($files as $file) {
              $cmd = sprintf('/usr/bin/php -f "%s" >> /dev/null &', $file);
              system($cmd);
          }
          

          soap-client-1.php

          $client = new SoapClient('http://www.webservicex.net/geoipservice.asmx?WSDL');
          
          $parameters = array(
              'IPAddress' => '8.8.8.8',
          );
          $result = $client->GetGeoIP($parameters);
          // @todo Save result
          

          每个 php 脚本都会启动一个新的 SOAP 请求并将结果存储在数据库中。现在您可以通过从数据库中读取结果来处理数据。

          【讨论】:

            【解决方案5】:

            这似乎是一个架构问题。相反,您应该使用单独的文件/URL 来使用每个服务,并将 JSON 从这些服务中抓取到 HTML5/JS 前端。这样一来,您的服务可以分成许多异步块,并且可以单独调整每个块的速度。

            【讨论】:

              猜你喜欢
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 2020-12-06
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              相关资源
              最近更新 更多