Самый быстрый или самый надежный способ сделать 7 запросов API мыла параллельно

мое веб-приложение требует выполнения 7 различных запросов API wsdl для выполнения одной задачи (мне нужно, чтобы пользователи ждали результата всех запросов). Среднее время ответа составляет от 500 мс до 1,7 секунды на каждый запрос. Мне нужно запустить все эти запросы параллельно, чтобы ускорить процесс. Как лучше всего это сделать:

  1. потоки или
  2. рабочие Gearman
  3. разветвление процесса
  4. curl multi (мне нужно построить тело мыла xml)

person nullException    schedule 03.03.2014    source источник
comment
Ни один из них не является оптимальным. Случайно вам не нужно ждать, пока они будут выполнены, прежде чем отправлять ответ обратно в стандартный вывод? (т.е. можно ли это сделать асинхронно?)   -  person phpisuber01    schedule 04.03.2014
comment
да. мне нужно вернуть все ответы перед выполнением задания   -  person nullException    schedule 04.03.2014
comment
+1 Не уверен, почему за этот вопрос проголосовали отрицательно; интересно узнать, можно ли отделить запрос/ответ от SoapClient.   -  person Ja͢ck    schedule 04.03.2014
comment
Вы по-прежнему хотите, чтобы SoapClient обрабатывал ответ?   -  person Ja͢ck    schedule 04.03.2014


Ответы (1)


Ну, первое, что нужно сказать, никогда не бывает хорошей идеей создавать потоки в прямом ответе на веб-запрос, подумайте о том, насколько это на самом деле масштабируется.

Если вы создадите 7 потоков для всех, кто придет, и появится 100 человек, вы попросите свое оборудование выполнять 700 потоков одновременно, что на самом деле довольно много, чтобы просить о чем-либо...

Однако масштабируемость — это не то, с чем я могу вам помочь, поэтому я просто отвечу на вопрос.

<?php
/* the first service I could find that worked without authorization */
define("WSDL", "http://www.webservicex.net/uklocation.asmx?WSDL");

class CountyData {

    /* this works around simplexmlelements being unsafe (and shit) */
    public function __construct(SimpleXMLElement $element) {
        $this->town = (string)$element->Town;
        $this->code = (string)$element->PostCode;
    }

    public function run(){}

    protected $town;
    protected $code;
}

class GetCountyData extends Thread {

    public function __construct($county) {
        $this->county = $county;
    }

    public function run() {
        $soap = new SoapClient(WSDL);

        $result = $soap->getUkLocationByCounty(array(
            "County" => $this->county
        ));

        foreach (simplexml_load_string(
                    $result->GetUKLocationByCountyResult) as $element) {
            $this[] = new CountyData($element);
        }
    }

    protected $county;
}

$threads  = [];
$thread   = 0;
$threaded = true; # change to false to test without threading

$counties = [     # will create as many threads as there are counties
    "Buckinghamshire",
    "Berkshire",
    "Yorkshire",
    "London",
    "Kent",
    "Sussex",
    "Essex"
];

while ($thread < count($counties)) {
    $threads[$thread] = 
        new GetCountyData($counties[$thread]);
    if ($threaded) {
        $threads[$thread]->start();
    } else $threads[$thread]->run();

    $thread++;
}

if ($threaded)
    foreach ($threads as $thread)
        $thread->join();

foreach ($threads as $county => $data) {
    printf(
        "Data for %s %d\n", $counties[$county], count($data));
}
?>

Обратите внимание, что экземпляр SoapClient не является и не может использоваться совместно, это может замедлить работу, возможно, вы захотите включить кэширование wsdl...

person Joe Watkins    schedule 04.03.2014