Как обеспечить передачу сообщений по запросу/опросу с веб-сервера

Это основано на Как отправлять сообщения между компаниями. Если я решу, что компания S (поставщик) должна опрашивать заказы от компании (B) каким-то простым способом на основе HTTP, что является лучшей реализацией.

  • Я предполагаю, что у компании B есть работающий веб-сервер, и внутренняя база данных этого веб-сервера надежна. Мы должны сделать как можно меньше предположений о процессах хранения в S и о том, могут ли они сохранять состояние (например, список уже переданных GUID).
  • Интернет-соединение между B и S ненадежно.
  • Мы должны достичь эвентуальной согласованности, что означает, что в какой-то момент времени все заказы между B и S должны быть перенесено.

Как лучше всего внедрить такую ​​систему?


person max    schedule 27.10.2010    source источник


Ответы (5)


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

Есть два возможных подхода, которые приходят на ум. Один из них — использовать надежный обмен сообщениями WS, который переносит проблему надежности на уровень веб-службы. инфраструктура. Другой — вручную запустить собственный надежный протокол поверх простых, но ненадежных сервисов.

У меня нет серьезного практического опыта внедрения системы с WS Reliable Messaging, я верю, что ее можно заставить работать, но она требует некоторой степени контроля над участниками — поскольку это сравнительно новый стандарт, мы не можем гарантия того, что у любого данного ИТ-магазина будет готовая реализация, и совместимость между поставщиками может быть проблемой. Чем больше у меня контроля над стеками SW на каждом конце, тем больше я склоняюсь к использованию WS Reliable Messaging. [Я также должен упомянуть WS Atomic Transaction, который также можно использовать для создания надежных сервисов, применимы те же проблемы взаимодействия.]

Так что насчет самокрутки? Ключевым моментом здесь является сделать все сервисы идемпотентными. Поскольку у нас нет транзакционных гарантий, охватывающих две системы, мы должны исходить из того, что любой конкретный вызов службы может завершиться неудачно с неизвестным результатом.

Я собираюсь предположить, что B хочет получить подтверждение того, что S принял заказ, поэтому нам нужно обновить информацию как в B, так и в S, когда заказ будет передан.

B должен предлагать следующие услуги:

 Give me the next order(s)

 I have stored {orders ...}

Итак, как мы определяем «следующий». Самый простой случай хорошо работает, если объемы, с которыми мы имеем дело, могут позволить нам иметь один «поток» передачи. Затем B отмечает отправленные заказы по одному, причем заказы имеют монотонно возрастающий ID. Затем мы можем упростить до:

 I have stored order <65,004> please give me the next

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

person djna    schedule 27.10.2010
comment
монотонно увеличивающиеся идентификаторы несколько сложны в электронной распределенной системе, но мы могли бы пойти с дополнительным: теперь я сохранил сообщение, вы можете удалить его по запросу. - person max; 27.10.2010
comment
Не могли бы вы привести пример веб-сервисов, стек WS-* кажется мне несовместимым сложным беспорядком, но это может быть только отсутствие у меня опыта работы с ним. Где найти библиотеки Ruby/Python/PHP/Perl для WS-* на Github? - person max; 11.11.2010

То, что вы, вероятно, ищете, - это двухфазная фиксация. Это хорошо описано в инете, вот например:

http://en.wikipedia.org/wiki/Two-phase_commit_protocol

Суть этого:

Процесс фиксации происходит следующим образом:

* Phase 1
      o Each participating resource manager coordinates local 
        operations and forces all log records out:
      o If successful, respond "OK"
      o If unsuccessful, either allow a time-out or respond "OOPS" 
* Phase 2
      o If all participants respond "OK":
            * Coordinator instructs participating resource managers to "COMMIT"
            * Participants complete operation writing the log record
              for the commit 
      o Otherwise:
            * Coordinator instructs participating resource managers to "ROLLBACK"
            * Participants complete their respective local undos 

Должен работать для любых данных.

person Roman Goyenko    schedule 02.11.2010
comment
Я думаю, что будет довольно сложно заставить другой конец реализовать (и протестировать) двухфазную атомарную фиксацию. - person max; 04.11.2010

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

Самый простой способ в вашем случае: как только сервер получает запрос на опрос, он отправляет x количество ответов, все с одним и тем же GUID. Например.

S: B, anything new?
S: B, anything new?
S: B, anything new?
B: Yes, S, I need a jacket (order #123).
S: B, anything new?
B: Yes, S, I need a jacket (order #123).
S: B, anything new?
B: Yes, S, I need a jacket (order #123).
S: B, anything new?
B: Yes, S, I need a jacket (order #123).
B: Yes, S, I need some shoes (order #124).
S: B, anything new?
B: Yes, S, I need a jacket (order #123).
B: Yes, S, I need some shoes (order #124).
S: B, anything new?
B: Yes, S, I need some shoes (order #124).
S: B, anything new?
B: Yes, S, I need some shoes (order #124).
...

S может быть заспамлен заказами, но так как # отправляется с каждым запросом, это не имеет большого значения. Если мы пропустили это раньше, мы получаем это сейчас. Если мы не получили его раньше, woohoo! У нас есть это сейчас. Система работает! Вы заметите, что в моем примере B отправляет сообщения 5 раз. В реалистичном сценарии вы, вероятно, отправите сообщение сотни или тысячи раз, пока не добьетесь желаемой надежности.

Приведенное выше решение требует интенсивной обработки и пропускной способности, но оно работает. Более умный метод — сделать то, что делает TCP: установить трехстороннее рукопожатие.

S: Hello B. Are you there? -> SYN
B: Hello S, yep I'm here. What's up? -> SYN+ACK
S: Oh good, you're there. -> ACK
S: B, anything new?
B: Yes, S, I need a jacket (order #123).

Но... HTTP уже делает это. Так что, если что-то не получится, вы будете знать. Время ожидания соединения истекло, соединение прервано и т. д.

Теперь вы можете переписать эти сценарии на уровне приложений (введите WS-ReliableMessaging), но на самом деле TCP уже надежен. Некоторые критики этих SOAP-фреймворков и фальшивых протоколов (обычно они работают поверх HTTP) обвиняют их в том, что они, по сути, заново изобретают колесо — и проблемы колеса — на более высоком уровне абстракции.

Суть в том, что любая система может дать сбой, включая надежные системы обмена сообщениями.

Что касается возможной согласованности, я думаю, вы можете быть сбиты с толку. Согласованность в конечном счете применяется только к распределенным системам хранения, где после Write() вы не сможете детерминировано получить его с помощью Read() в течение некоторого времени. Это совсем не похоже на вашу проблему. Я имею в виду, я понимаю, что вы говорите, но в системе eventually consistent предполагается надежное (достаточно) соединение между узлами. Вы не делаете этого предположения (хотя я думаю, что вы должны .. TCP чертовски надежен).

person David Titarenco    schedule 03.11.2010
comment
Интересный комментарий. То, что я описываю, действительно может быть смоделировано как распределенная система хранения, но, опять же, большинство распределенных систем могут. Если подумать, ваш подход к повторению и ссылке на TCP атакует не ту проблему (вероятно, я описал это неуклюже). Между компаниями IP-соединение не работает (нет проблем, просто повторите попытку) или работает. Но серверные системы довольно часто не работают, или не могут обработать этот символ, отличный от ASCII, или имеют переполнение буфера для адресов электронной почты длиннее 35 символов ... так что это больше касается повторной попытки в нужном месте. - person max; 04.11.2010

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

S ---> D ( Call a service which would list record keys)
D----> S ( provide xml of keys)
S----> D ( Request each of the records)
D----> S ( Submit record)

В случае создания новой записи после синхронизации Destination может вызвать службу, развернутую в источнике, которая обработает новую запись.

Поскольку связь обрабатывается с помощью механизма веб-службы, вам не нужно беспокоиться о параметрах сообщения. SSL можно добавить для безопасности.

Ваше здоровье!

person Ricko M    schedule 09.11.2010

Я думаю, вы пытаетесь сказать, что компания Б является пассивным участником. S (поставщику) просто нужна возможность получать все заказы, которые публикует B (возможная согласованность). Но B не нужны и не заботятся о том, какие заказы уже есть у S (нет необходимости в фиксации).

Если у компании B есть полуточные часы, вы можете использовать дату в качестве монотонно возрастающего GUID, в зависимости от разрешения событий — вы не захотите опрашивать, если вам все равно нужно разрешение в миллисекундах. Вы используете только часы B, поэтому вам не нужно беспокоиться о синхронизации. Если B публикует все заказы, S может просто взять заказы с того места, где он остановился в последний раз.

Я не уверен, имели ли вы в виду лучшие практики или лучшие компромиссы для простой в реализации системы. В зависимости от объема и времени отклика нет необходимости делать его динамической системой, если вы все равно проводите опрос. Выгружайте заказы в виде текстовых файлов (названных по отметке времени) в каталог с именем по дате и извлекайте их все (или выборочно). Вы даже можете хранить их в каталогах по часам или как угодно. HTTP GET является идемпотентным.

Это может быть некрасиво, но похоже, что вы не ожидаете особых сложностей от компании B. Используйте SSL и аутентификацию, и они заблокированы и зашифрованы.

Если вам не нужна производительность, в простом нет ничего плохого. Что вы действительно получаете от сложного протокола?

person Bradley Kreider    schedule 09.11.2010
comment
Хорошая идея опроса с интервалом в минуту или около того и, таким образом, ослабление требования синхронизации часов. - person max; 10.11.2010