вторник, декабря 19, 2006

Односторонние соединения web сервисов и о пользе стандартов.

Не так давно, мне пришлось решать вот такую задачу. Есть две системы A и B. Система A должна обращаться к web сервису системы B, передавая ей некоторые данные и получая назад результаты расчета. Загвоздка была в том, что система A расположена в DMZ (Demilitarized Zone – специальный домен на границе внутренней сети и Интернета), а система B - во внутренней сети компании. Между ними, на границе сетей стоит firewall. Обычный такой firewall, и сконфигурирован как обычно: пропускает только запросы, инициированные из внутренней сети наружу (в DMZ). Т.е. установить соединение от системы A к системе B невозможно. Пришлось придумывать workaround, изменять направление потока сообщений и сигнатуры методов. Теперь система B периодически опрашивает систему A на предмет наличия запросов. При наличии ожидающего запроса система A возвращает его в респонсе. Система B производит вычисления и отправляет результат назад, путем вызова другого метода в системе A. Иными словами простая схема взаимодействия:


Заменена на сложную схему взаимодействия:

И ведь это еще не все. В системе А пришлось организовать внутреннюю очередь для хранения запросов к системе В в промежутках между опросами. Как видно из второй диаграммы, операция расчета стала асинхронной, поэтому пришлось уникально идентифицировать запросы, чтобы установить соответствие между запросами и результатами расчетов. Кроме того, пришлось ввести дополнительный SOAP заголовок, сигнализирующий системе B о наличии в очереди необработанных запросов, для того чтобы инициировать «внеплановые» опросы B-A при наличии ожидающих в очереди запросов. Это необходимо, для того, чтобы система могла адаптироваться к нагрузке.

В общем, все закончилось хорошо, решение проблемы было найдено. Если вы думаете, что это не типичный случай – вы глубоко заблуждаетесь. Все firewall-ы на границах локальных сетей компаний сконфигурированы одинаково. Они пропускают запросы из внутренней сети наружу и задерживают запросы из внешней сети во внутреннюю. И если вам необходимо организовать взаимодействие двух систем в разных сетях вы наверняка столкнетесь с такой ситуацией «одностороннего» соединения.
И вот недавно, мне попалась на глаза статья Дага Дэвиса (Doug Davis) из IBM под мудреным названием «Взаимодействие между WS-сервисом надёжной передачи сообщений (WS-RM) и WS-механизмом опроса (WS-Polling)». Несмотря на название, в статье рассматривается какие методы рабочая группа протокола WS- ReliableMessaging предлагает для борьбы с клиническим случаем, одно из проявлений которого я вам только что описал. И знаете, что меня порадовало в этой статье? То что, зубры из технических комитетов W3C, OASIS и других уважаемых организаций, все-таки не зря получают пэйчеки в своих конторах. О конкретной моей проблеме знают в техническом комитете OASIS, и над ней работают. И это радует. Сколь бы сложными и запутанным не казались нам все эти спецификации сетевых сообществ, они в конечном итоге делают проще нашу с вами жизнь – рядовых разработчиков и проектировщиков. В статье очень подробно расписано, как данная проблема будет решаться на уровне расширения SOAP протокола, которым является спецификация WS-RM. Также приводится альтернативный вариант решения на основе протокола WS-Polling, рассматриваются его преимущества и недостатки.
Насколько я понял, спецификация WS-RM близка к принятию, а ее поддержка уже встроена в WCF (во всяком случае, стандартные привязки с настраиваемым уровнем гарантированной доставки есть). Я, правда, пока не понимаю, как в WCF реализовать поддержку описанного в статье сценария стандартными средствами. Возможно это предмет для будущих версий фрэймворка.
Ссылки по теме

3 комментария:

Anton комментирует...

Вот мне всегда хотелось в таких случаях использовать messaging. Чтобы в случае нужды система A посылала сообщение системе В. Желательно, по стандартному и насмерть защищённому протоколу, типа того же MSMQ.

Sergey Rozovik комментирует...

Для надежной доставки - да MSMQ рулит. Но если канал "односторонний" - очереди мало чем помогут. От A к B могут идти только респонсы но не реквесты. MSMQ все равно будет использовать какой-то транспорт (TCP или HTTP) и тут мы упираемся в это ограничение.

Anton Terekhov комментирует...

Это понятно, и предложенное решение вполне адекватно ситуации. Однако если смотреть с общем случае, то я не вижу логического обоснования этого ограничения. Ведь для MSMQ дырочка, которую надо проковырять в firewall, очень мала. Фактически, это одно заранее известное сообщение от известной системы А известной системе В по заранее известному протоколу. Возможно я ничего не понимаю, но мне кажется, что никаких security рисков это не добавляет.