четверг, 15 декабря 2016 г.

[prog] Вопрос по организации связей между узлами/процессами на базе открытых стандартов и/или протоколов

Допустим, что у нас есть десяток-полтора узлов внутри локальной сети. На каждом узле работает свой набор прикладных процессов. Разных процессов. Процессы должны обмениваться между собой данными. Например, процесс A должен отослать сообщение процессу B, процесс B -- процессу C, процесс C -- процессу D, процесс D -- процессам A и B. При этом процессы A и B могут работать на одном узле, процессы C и D -- на разных узлах. Взаимодействие может быть как в режиме fire-and-forget, так и в режиме request-reply. Но больше, все-таки, в режиме fire-and-forget. Поток сообщений более-менее приличный: от нескольких десятков тысяч сообщений, до сотни тысяч. Размер сообщений относительно небольшой, порядка 1.5-2 килобайт.

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

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

Поэтому можно смотреть и в сторону peer-to-peer взаимодействия. Например, на базе модного нынче REST-а. Получится, что в каждом процессе открывается HTTP-вход, на который и приходят REST-запросы. Процесс A делает REST-запрос к процессу B, процесс B делает запрос к процессу C и т.д. Все знают URL-ы процессов, с которыми взаимодействуют и могут сделать запрос напрямую. Что хорошо.

Проблема с REST-ом в том, что он отлично ложится на взаимодействие request-reply. А вот для fire-and-forget уже не так хорошо: зачем, спрашивается, делать отдельный HTTP POST, пусть даже и по keep-alive соединению, если ответ нам все равно не нужен (как и подтверждение доставки)? Понятное дело, что современные HTTP-сервера способны обрабатывать сотни тысяч запросов на одном ядре. Но все-таки...

Как я понимаю, под такие задачи хорошо ложится, например, система взаимодействия процессов в Erlang-е. Там процесс A знает PID процесса B и просто отсылает B сообщения. Если A и B оказались на одной ноде в рамках одной Erlang VM, то для доставки сообщения вообще никаких внешних IPC не будет задействовано. Проблема в том, что это Erlang-овая кухня, которая не подойдет, если нужно организовать интероперабильность процессов, реализованных на разных языках программирования (например, C++, Java, Python).

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

PS. Вопрос вызван не какой-то конкретной задачей, а попыткой осмыслить подходы к реализации нескольких систем, о которых довелось узнать.

Отправить комментарий