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. Кто еще их не попробовал, рекомендую это сделать.

    Похожие публикации

    AdBlock похитил этот баннер, но баннеры не зубы — отрастут

    Подробнее
    Реклама

    Комментарии 29

      –2
      cooike — очепятка :D
        +1
        Простите а что значит не нужны WSDL схемы?)
        если нет — то значит не нужен стандарт, не нужен стандарт — незачем применять столь громоздкую системы.
        Вообще, SOA решения, подходят больше для энтерпрайза.
        В остальных вариант, можно подобрать более экономичное как по ресурсам так и по скорости обработки решение
          0
          Потому что стандарт SOAP не обязывает использовать WSDL.
            0
            SOAP — да
            В приведенном выше случаем, я описал причины использования.
              0
              Стандарт WSDL также не обязывает использовать SOAP.
            0
            Не все методы надо открывать на общий обзор, о некоторых лучше знать только вам.
              0
              Как это связано с WSDL?
              WSDL не обязывает описывать абсолютно все методы
                0
                Ну так сервис по конкретному адресу может быть, а wsdl не быть.
                  0
                  всё равно не понял, как это влияет на тот факт, что я, возможно, захочу скрыть несколько методов «на будущее»? Я могу не упоминать в документации об определенном методе SOAP сервиса, но я также могу и не описывать этот метод в WSDL и никто о нём не узнает. Мы вообще с Вами об одном и том же? :)
            0
            Спасибо, о PHP-оракул:) Как-нибудь попытаюсь использовать.

            Но так сложилось, что я просто ненавижу SOAP, но блин использовать по работе приходится. На редкость геморная технология.
              0
              Подозреваю, что ненависть эта связана с WSDL-схемами. Они, как тут выше правильно заметили, «подходят для энтерпрайза». Попробуйте без них, в большинстве случаев жизнь становится сильно легче. Без WSDL PHP-шный SOAP превращается в простой и приятный инструмент, да и с точки зрения ресурсов все достаточно хорошо (по сравнению с обычными издержками на выполнение PHP-кода накладные расходы на SOAP-кодирование и декодирование блекнут).
                0
                Вообще-то самое долгоиграющее — это коннект и запросы к удаленному серверу.

                Скорость выполнения кода не имеет существенного значения. Хоть с WSDL, хоть без него.
                  +1
                  С ростом числа параллельных запросов накладные расходы на коннект и сетевое взаимодействие становятся всё менее существенными и рано или поздно растворяются на фоне полезных вычислительных расходов.
                    +1
                    Мгм, боюсь, вы не сможете выдать адекватное число параллельных запросов, чтобы последняя фраза стала правдой.

                    Более того, накладные расходы(впустую затрачиваемое процессорное время) будут только расти. И SOAP тут совсем не причем. Вы можете лишь сократить время отклика системы.

                    SOAP выгоден не из-за возможности распараллелить, а из-за возможности сосредоточить тяжелые вычисления в одном месте, а результатами пользоваться в любом другом месте. Плюс, не требуется реализовывать у себя существующий(где-то) функционал — вы просто пользуетесь уже реализованным.
                  +1
                  без WSDL SOAP превращается в страшного монстра, по моему мнению. Страшным как со стороны API
                  : ну что это за $client->__call('method', array('var1', 'var2')); вместо $client->method('var1', 'var2');
                  , так и со стороны самого формата передачи данных. Всё-таки с XML-RPC в данном случае (буз wsdl), получится лучше
                    0
                    > ну что это за $client->__call('method', array('var1', 'var2')); вместо $client->method('var1', 'var2')
                    Действительно, что это за ужас?
                    В PHP-версии SoapClient (и, следовательно, в Dklab_SoapClient) всегда пишется вторая версия, а первая не нужна. WSDL тут ни при чем.
                  0
                  REST скоро вытеснит СОАП
                  0
                  Собственно, если исходить из посылки, что нужно иметь вот это:
                  «При помощи этой библиотеки вы можете, например, строить страницу вашего сайта из блоков, как из конструктора. Каждый блок запрашивается через SOAP отдельно и независимо от других, при этом все запросы происходят параллельно. Если один из блогов не уложился в отведенное ему время (тайм-аут), то его можно не отображать на странице.»
                  то гораздо лучше подойдут nginx'овские ssi.
                  С их помощью можно:
                  — Одновременное, параллельное выполнение запросов
                  — Реконнект при невозможности установления связи (даже лучше, можно отправлять иметь пул серверов и балансировать запросы между ними, если один сервер не ответил, то можно отправить запрос на другой)
                  — Поддержка тайм-аута на получение данных

                  + к этому нет оверхеда на использование SOAP (кодирование/декодирование ответа, оверхед на сами SOAP месседжы и т.п.). Можно еще положить эти самые сгенеренные блоки в memcached и попросить nginx проверять их там; если найдется закешированный блок, то до php денло вообще не дойдет; блоки можно кешировать с различным TTL.

                  В общем, я не вижу ни одного преимущества этого SOAP решения против описанного мной, кроме немного более удобной передачи аргументов в вызов, однако на этом и все.
                    0
                    А вы не рассматривайте SOAP, как технологию сборки страниц, это скорее технология построения mashup для сервисов, где ssi совсем не помощник.

                    Просто автор пытается донести преимущества своего продукта в понятном виде для веб-разработчиков(сайтостроителей) :)

                    Но вот зачем им(сайтостроителям) SOAP — тут я затрудняюсь ответить :)
                      0
                      Например для реализации хостинговой панели управления.
                      Получается очень хорошо и просто, потому что не нужно задумываться о проектировании нового протокола, а SOAP очень подходит для этой модели.

                        0
                        А раскрыть свою мысль поподробнее?

                        Просто, меня смущает применение SOAP для коммуникации в рамках одного приложения — это слишком накладно и бессмысленно на мой взгляд. А вот для связи нескольких приложений — другой вопрос.
                          0
                          Ну вот смотрите.
                          Например у меня есть панель, написанная на php.
                          Пользователи с помощью нее делают различные настройки(изменяют данные в dns, создают ftp аккаунты, меняют пароли пользователей баз данных, etc).
                          На каждом сервере(обычном пользовательском, служебных(dns, большие mysql на несколько тысяч пользователей)) находится серверная панель написанная, например на perl.
                          Взаимодействие осуществляется примерно так — пользователь что-то ткнул у себя в панели, скрипт послал нужный soap request на нужный сервер, выполнилась нужная команда. И вот для такой схемы, когда нам нужна активная схема выполнения команд(а не пассивная, как например в случае наличия какого-то spool'а, который периодически читают все сервера с поиском комманд для выполнения именно для себя), SOAP очень хорошо подходит. Потому что нам не нужно мучаться с проектированием протокола, что по себе является достаточно сложной вещью. Плюс имея актуальную WSDL схему, мы практически имеем полное описание протокола.

                          Если ответил как-то не понятно — простите =)
                        0
                        Так я ж и не говорю, что SOAP — плохо. Я просто сказал, что пример использования плохой.
                        К примеру, на одном из моих проектов SOAP используется для предоставления API по управлению пользовательским контентом. Т.е. пользователь может залогиниться на сайт и там управлять своим контентом (от десятка до сотни тысяч единиц контента), а может использовать SOAP API для интеграции со своим софтом или просто поюзать десктопную софтинку, которая говорит с проектом по этому SOAP API. И мне хорошо (снижается нагрузка за счет отсутсвия рендеринга страниц) и пользователю удобно.
                        0
                        Про nginx SSI Вы правы, в ряде случаев он оказывается удобнее. Дописал про это в dklab.ru/lib/Dklab_SoapClient/#cont8 — спасибо.
                        0
                        А почему выбран блог «Высокая производительность», а не PHP? Разве SOAP актуален только при построении высокопроизводительных систем?
                          –1
                          Да, особенно когда речь идёт о параллельных вызовах.
                            0
                            Вы хотите сказать, что на простеньком корпоративном сайте, построенном по предложенной блочной технологии, который посещают 500 человек в день, не нужно параллельно подгружать блоки? И можно позволить, что бы такой сайт открывался не 0.5 с, а 5.0 с?
                              0
                              Кажется очевидно что пример блоков для корпоративного сайта тут просто взят абстрактно. Есть множество задач в проектах с распределённой архитектурой которые требуют распараллеливания.
                          0
                          Ну и самый больной вопрос: SOAP c Attachment оно умеет?

                          Только полноправные пользователи могут оставлять комментарии. Войдите, пожалуйста.

                          Самое читаемое