Как стать автором
Обновить

SoapClient: параллельные асинхронные запросы, реконнект, обработка тайм-аутов

Высокая производительность *
Dklab_SoapClient — это расширенная версия стандартного PHP-класса SoapClient, предназначенная для параллельного (асинхронного) удаленного вызова процедур в высоконагруженных проектах.

При помощи этой библиотеки вы можете, например, строить страницу вашего сайта из блоков, как из конструктора. Каждый блок запрашивается через SOAP отдельно и независимо от других, при этом все запросы происходят параллельно. Если один из блогов не уложился в отведенное ему время (тайм-аут), то его можно не отображать на странице.

По сравнению со встроенным в PHP SoapClient, поддерживаются дополнительные возможности:
  • Одновременное, параллельное выполнение запросов к нескольким удаленным процедурам — ключевая особенность библиотеки. Если страница на вашем сайте собирается из 5 удаленных блоков, каждый из которых генерируется по 100ms, их можно запустить параллельно и получить всю страницу целиком не за 500ms, а за те же самые 100ms.
  • Реконнект при невозможности установления связи. К сожалению, мир несовершенен, и из-за случайной потери пакетов первая попытка соединения с SOAP-сервером может закончиться тайм-аутом. Это особенно часто происходит, когда проект располагается в нескольких датацентрах. Dklab_SoapClient позволяет задать тайм-аут на время открытия соединения (например, 1 секунду) и, в случае неудачи, повторить попытку указанное число раз. На практике это снижает вероятность итогового сбоя в тысячи раз, т.к. реконнект почти всегда помогает при утере пакета.
  • Поддержка тайм-аута на получение данных. Если страница собирается из удаленных блоков, то в случае «подвисания» одного из них «зависает» и вся страница. В то же время, отсутствие одного из блоков при наличии остальных — не такая большая беда. Вы можете указать, сколько времени Dklab_SoapClient должен ждать ответа от удаленной процедуры; если время превышено, возникает исключение PHP, которое вы можете обработать по своему усмотрению, не прерывая загрузку остальных блоков.
Почему именно SOAP? С первого взгляда может показаться, что это очень громоздкий протокол, который сложно применять. Однако, если не копаться во внутренностях протокола, оказывается, что в PHP SOAP использовать очень удобно. Если не нужны WSDL-схемы, простейший SOAP-сервер пишется так:

class MyServer
{
    public function getComplexData($some)
    {
        sleep(1); // типа, эмулируем тяжелый код
        return array("obj" => (object)array("prop" => $some), "some" => "thing");
    }
}
$soapServer = new SoapServer(null, array('uri' => 'urn:myschema'));
$soapServer->setObject(new MyServer());
$soapServer->handle();

А соответствующий ему SOAP-клиент — вот так:

require_once "Dklab/SoapClient.php";
$client = new Dklab_SoapClient(null, array(
    'location' => "http://example.com/server.php",
    'uri' => 'urn:myschema',
    'timeout' => 3,
));
// Запросы выполняются параллельно, асинхронно. В сумме - за 1 с.
$query1 = $client->async->getComplexData(array("abc"));
$query2 = $client->async->getComplexData(array("xyz"));
print_r($query1->getResult());
print_r($query2->getResult());

Что важно, при работе с SOAP в PHP сервер может возвращать данные в произвольном формате (например, массив массивов объектов), а клиент — передавать серверу в параметрах переменные любой структуры (к примеру, тот же самый массив массивов объектов). При этом все преобразования выполняются автоматически.

Т.к. Dklab_SoapClient — это расширение встроенного SoapClient, поддерживаются все стандартные возможности последнего, в числе которых:
  • Работа с Cookies. Одна процедура может вызвать setcookie(), а другая — прочитать значение этой cooike позже.
  • Работа с PHP-сессиями. Одна процедура пишет данные в сессию, вторая — читает.
  • Поддержка WSDL-схем и передача сложных бизнес-объектов.
  • Обработка исключений, возникающих в удаленной процедуре.
Если вдруг Apache Thrift для вашего проекта — «из пушки по воробьям», Dklab_SoapClient может послужить простой и компактной альтернативой. (Кстати, в PHP-модуле для Thrift не поддерживаются параллельные запросы — по крайней мере, я их там не нашел.)

Посмотреть документацию, примеры, автотесты и скачать библиотеку можно здесь: http://dklab.ru/lib/Dklab_SoapClient/

P.S.
Кстати, при разработке используется Git и социальная сеть GitHub. Кто еще их не попробовал, рекомендую это сделать.
Теги:
Хабы:
Всего голосов 38: ↑34 и ↓4 +30
Просмотры 6.7K
Комментарии Комментарии 29