LINUX.ORG.RU

Современный быстрый RPC

 , ,


2

3

Хочу написать программу. Идеологически хочу её сделать как пачку микросервисов, но не хочу привязываться к конкретному языку программирования.

Поэтому нужен протокол для общения между микросервисами. Нашёл https://github.com/hprose : высокая скорость, много поддерживаемых языков. Но хочу уточнить, может есть уже что-то более популярное.

★★★★★

Ответ на: комментарий от ugoday

Потому что на 10 байт и 100 тактов функции получаем 100 байт заголовков и 1000 тактов сериализации и десериализации.

Кроме того, JSON не умеет структуры со ссылками.

monk ★★★★★ ()

Идеологически хочу её сделать как пачку микросервисов

Как говорил один senior на собеседовании: «Монолит - это одна большая куча говна, а микросервисы, это когда много маленьких горок говна.»

DELIRIUM ★★★★★ ()
Ответ на: комментарий от hippi90

REST тормозной. И внутри одного соединения несколько запросов не позволяет.

MQ — это который очереди сообщений? Их тоже вагон: zMQ, IBM MQ, RabbitMQ, ... Я не смог понять, как на нём писать, не превращая код в лапшу из обработчиков обратных вызовов. Синхронные вызовы там вроде не предусмотрены.

monk ★★★★★ ()

Идеологически хочу её сделать как пачку микросервисов

Это профитно для очень редкого класса задач, к которым твоя программа не относится явно.

devl547 ★★★★★ ()
Ответ на: комментарий от DELIRIUM

protobuf + grpc смотрел. В первый момент отпугнула необходимость генерации кода. Теперь смотрю повторно, судя по наличию независимых реализаций на PERL и Rust, похоже, действительно от языка не зависит.

Благодарю!

monk ★★★★★ ()
Ответ на: комментарий от devl547

Это профитно для очень редкого класса задач, к которым твоя программа не относится явно.

А как ещё скрестить разные языки программирования в одной программе?

monk ★★★★★ ()
Ответ на: комментарий от hippi90

Не пиши на жабаскрипте, делов-то.

Покажи пример на любом языке, как через MQ запросить данные и подождать ответа? То есть то, что обычно выглядит как result = conn.query(q).

monk ★★★★★ ()

Самые «быстрые» из общеизвестных rpc протоколы это, насколько мне известно, fast и sbe. От языка протокол не зависит по определению.

Если тебе нужна библиотека, то она по определению реализована для конечного множества языков.

Микросервисы то хоть stateless будут? Или хочешь пост модную тему заюзать просто?

pon4ik ★★★★★ ()
Ответ на: комментарий от monk

result = conn.query(q)

Тебя не смущает, что MQ работает немного, вот прям самую малость не так?

MQ - это про асинхронный обмен сообщениями, а ты хочешь синхронный. В общем случае, у тебя две очереди: MYSERVICE.QUEUE.REQ и MYSERVICE.QUEUE.RESP, запрос кидаешь в первую очередь, ответ ждешь из второй.

hippi90 ★★★★ ()
Ответ на: комментарий от hippi90

Так я именно это в первом сообщении и написал. Что MQ даёт только асинхронный протокол, а синхронного нормального нет.

ответ ждешь из второй

При этом если сервер вдруг перезагрузился до того, как успел ответить (но после получения запроса), то ты про это не узнаешь. То есть надо ещё городить почти-TCP поверх.

monk ★★★★★ ()
Ответ на: комментарий от monk

В ОП ты не сказал, что тебе позарез нужен синхронный обмен сообщениями, в этом случае да, MQ тебе не подойдет, согласен.

В целом, REST (и вообще протоколы поверх HTTP) наиболее языконезависимый и популярный протокол, JSON (кстати, никто не заставляет тебя передавать именно его, это просто наиболее популярный вариант, ибо JS) парсится довольно легко, накладные расходы там небольшие.

Ну и ты не сказал, насколько быстро тебе надо обмениваться сообщениями. Сколько rps ты хочешь?

hippi90 ★★★★ ()
Ответ на: комментарий от pon4ik

это, насколько мне известно, fast и sbe

Что-то они мало распространены...

От языка протокол не зависит по определению.

Есть Erlang distribution protocol, Racket distributed places, Java RMI.

Если тебе нужна библиотека, то она по определению реализована для конечного множества языков.

Должно быть достаточно много реализаций и возможность добавлять языки без обращения к разработчику протокола. Protobuf подходит.

Микросервисы то хоть stateless будут?

По построению предполагается, что да. Но номер сессии передаётся (для контроля доступа). Никто не может запретить держать контекст в кэше какое-то время.

Или хочешь пост модную тему заюзать просто?

Если честно, сначала структура программы определялась «как у qmail».

monk ★★★★★ ()
Ответ на: комментарий от hippi90

В ОП ты не сказал, что тебе позарез нужен синхронный обмен сообщениями, в этом случае да, MQ тебе не подойдет, согласен.

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

Ну и ты не сказал, насколько быстро тебе надо обмениваться сообщениями. Сколько rps ты хочешь?

По десятичному порядку величины около 1000 запросов в секунду. То есть до 10000.

monk ★★★★★ ()
Ответ на: комментарий от monk

Что-то они мало распространены...

Так быстро мало кому нужно, что бы заморачиваться, есть реализации которые представление в памяти за сотни наносекунд пакуют :)

На самом деле да, protobuf вполне годно. Если хочется чуть больше удобства в плане api, посмотри ещё на thrift, но, там чуть сильнее привязка к фреймворку.

pon4ik ★★★★★ ()
Ответ на: комментарий от anonymous

protobuf/grpc делает сообщения в несколько раз меньше, чем MessagePack. А если брать динамику, то лучше HPROSE (который я в начале упоминал). Тот же MessagePack, но с возможностью указания ссылок и передачи объектов как объектов, а не словарей.

monk ★★★★★ ()
Ответ на: комментарий от monk

Всё же, прежде, чем говорить о размерах сообщений и прочих «производительно», следует понять нефункциональные требования.

Сколько вызовов в секунду? Какие требования к каналу? А то, может оказаться, что выбрать json rpc окажется гораздо более мудрым решением, нежели смотреть в сторону бинарных решений.

pon4ik ★★★★★ ()
Ответ на: комментарий от pon4ik

Если хочется чуть больше удобства в плане api, посмотри ещё на thrift, но, там чуть сильнее привязка к фреймворку.

Пишут, что protobuf компактней и быстрей. Метод использования почти идентичен. И язык программирования к компилятору thrift не очевидно, как добавлять, если вдруг нужного нет.

monk ★★★★★ ()
Ответ на: комментарий от pon4ik

Сколько вызовов в секунду? Какие требования к каналу?

Порядка 1000 (до 10000) сообщений в секунду. Канал 100 Мб/с.

А то, может оказаться, что выбрать json rpc окажется гораздо более мудрым решением, нежели смотреть в сторону бинарных решений.

Может. Основной критерий: удобство написания модулей. Автор модуля должен иметь возможность на любом языке вызывать уже опубликованные функции и иметь возможность описать свои типы данных и функции. То есть должно быть что-то типа микрософтовского COM только без опоры на ОС.

monk ★★★★★ ()
Ответ на: комментарий от monk

10ms на сообщение в пике?

Да очередь из китайцев, которые на воздушных самолётиках записками обмениваются, может быть сопоставимой по производительности:)

Ну, зависит ещё конечно от размера сообщений, но по факту, имхо ты не заметишь разницы между jsonrpc и sbe(можно 10млн в секунду на определённом железе выдавать и парсить и ещё полезное что-то делать успевать) в своём приложении, а вот простота интеграции может заметно повысится.

pon4ik ★★★★★ ()
Ответ на: комментарий от monk

Только такой тонкий момент - 100us, это сильно меньше, чем квант в стандартном планировщике на десктопном железе.

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

Ну тут сильно ещё зависит от того, что именно ты делаешь и можно ли будет под него тонко настраивать целевую систему.

pon4ik ★★★★★ ()
Ответ на: комментарий от pon4ik

Только такой тонкий момент - 100us, это сильно меньше, чем квант в стандартном планировщике на десктопном железе.

А какое отношение ко всему этому имеет квант планирования?

tailgunner ★★★★★ ()
Ответ на: комментарий от tailgunner

Ну, если речь идёт о в сценарии когда это всё будет запущенно даже на локалхосте (без допнастроек) трупут то будет целевой, а вот времени отклика точно не будет. Я в основном к тому, что автор пропускную способность объявил а вот о времени отклика умолчал.

Вот ещё интересный график про 10G канал и время отклика, у людей которые старались.

pon4ik ★★★★★ ()
Ответ на: комментарий от pon4ik

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

Это сервер. Пользователь может генерировать до 50-100 сообщений в секунду в пике (например активно листает список). Пользователей планируется 10-100.

monk ★★★★★ ()
Ответ на: комментарий от pon4ik

Ну, если речь идёт о в сценарии когда это всё будет запущенно даже на локалхосте (без допнастроек) трупут то будет целевой, а вот времени отклика точно не будет.

А причем здесь квант планирования?

Вот ещё интересный график про 10G канал и время отклика, у людей которые старались.

А здесь квант планирования причем?

tailgunner ★★★★★ ()
Ответ на: комментарий от tailgunner

Очень просто: если у тебя n сервисов, они общаются по ipc. Т.е. разделяют время cpu на уровне квантов выдаваемых процессу. Когда у тебя взаимодействуют потоки в рамках одного приложения, весь квант выделенный процессу - твой. Когда это отдельные процессы, и их больше чем ядер, то забудь про время отклика в 100us, ведь если ты проспал начало пика, то будь добр подождать пока поработают все остальные ребята(и не факт, что они возьмут и уснут все по очереди, хотя даже на это уйдёт не меньше той самой сотни микросекунд).

Соответственно, при определённой продолжительности пика будет копиться отставание, как минимум на время обхода всей таблицы процессов. Какой нить FIFO и развешивание процессов и потоков приложений по ядрам это частично решает, но кто же будет заниматься этим на десктопе?

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

pon4ik ★★★★★ ()
Ответ на: комментарий от monk

А, так речь про ui. Там видимо если в пике произойдёт отставание даже на сотню миллисекунд, никто особо ничего не заметит.

Я бы на твоём месте написал бенч для на порядок худшей ситуации для nodejs(или на чём тебе удобней сервер делать) и jsonrpc. Надо только подумать, как эмулировать кратковременные всплески активности пользователей. Что-то мне подсказывает даже этих ребят для такого дела хватит за глаза. А плагины на jsonrpc это дюже модно.

pon4ik ★★★★★ ()
Ответ на: комментарий от monk

100000 откликов по 1КБ

Это, лишь говорит о том, что через секунду, все сообщения получат ответ. А вот сколько времени в рамках одной секунды пройдёт между ответом на сообщение 200 и сообщение 99999 никто ничего не обещает - может пройти 1ms а может 999ms.

pon4ik ★★★★★ ()
Ответ на: комментарий от monk

При этом если сервер вдруг перезагрузился до того, как успел ответить (но после получения запроса), то ты про это не узнаешь. То есть надо ещё городить почти-TCP поверх.

Это зачем? Обработчик получает сообщение и говорит что он его получил, потом делает все что нужно с этим сообщением (в том числе и отправляет ответ) и после этого говорит что закончил его обработку. Если он перегрузится где-то в середине - MQ вернет сообщение в очередь после определенного тайм-аута, и его подхватит другой воркер. Соответственно на случай перезагрузки тебе надо транзакции в БД городить или что-то еще, связанное с целостностью данных, а уж о сообщениях париться не стоит - это работа сервера очередей.

MQ даёт только асинхронный протокол

Это «не баг, а фича», микросервисы и должны быть асинхронными.

micronekodesu ★★ ()
Ответ на: комментарий от pon4ik

Очень просто: если у тебя n сервисов, они общаются по ipc. Т.е. разделяют время cpu на уровне квантов выдаваемых процессу

Это относится только к вычислительным задачам. Какую роль квант планирования играет там - понятно.

весь квант выделенный процессу - твой.

Квант выделяется нити (то, что ты называешь «потоком»), а не процессу. Впрочем, для IO-bound задач это не играет роли - там нить никогда не вырабатывает свой квант до конца.

Я не говорю, что это критично конкретно в случае автора

А. То есть квант не причем, а я уже заволновался.

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

Микросервисы здесь тоже не причем.

tailgunner ★★★★★ ()
Ответ на: комментарий от tailgunner

Квант выделяется нити

А я то думал, что в RR планировщике квант таки выделяется нитям процесса, в порядке обхода таблицы процессов, а затем планируются уже потоки. И, на один процесс в системе в среднем, выделяется что-то порядка 10ms.

нить никогда не вырабатывает свой квант до конца

Об чём и речь, после этого происходит своим чередом процесс планирования, который конечно реализован эффективно, но всё равно имеет не нулевую стоимость.

pon4ik ★★★★★ ()
Ответ на: комментарий от micronekodesu

Если он перегрузится где-то в середине - MQ вернет сообщение в очередь после определенного тайм-аута, и его подхватит другой воркер.

А куда посмотреть, как это настраивается? Можно ссылку?

Это «не баг, а фича», микросервисы и должны быть асинхронными.

Микросервисы — да, а их клиенты — не всегда. Так как бывает ситуация, когда клиенту-человеку надо уточняющий вопрос задать. Но если MQ обрывы связи нормально обрабатывает, то этого достаточно.

monk ★★★★★ ()