Comments 25
Мне кажется что есть более простой вариант для "Распространение protobuf модели". Каждый сервис хранит модель у себя. Клиенты ее импортируют (тут конечно зависит от ЯП, ка реализовать импорт). И за использовать тулу чтобы не ломать бек совместимость proto. Монорепа в крупных компаниях делается не для этого и никто не хранит там все протофоайлы в одной директории.
Проблема в том, что из proto файла protoc генерирует исходный код для клиента и сервера. То есть, модель требуется во время компиляции клиента, а во время выполнения proto файл не нужен ни клиенту, ни серверу. Чтобы воспользоваться proto во время выполнения, клиент должен уметь перекомпилировать свой код. На C# в некоторых случаях мы так и делаем. Но это всё же скорее исключение, чем правило. Например, когда сервер, обнаружив изменение метаданных во внешнем источнике, обновляет свой proto файл, публикует его и перекомпилирует изменившиеся классы.
Когда все на одном ЯП, можно сделать пакет. Монорепа подходит в том числе и для контрактов, удобный паттерн
grpc-web не поддерживает подписку на сообщения через websocket и выжидают пока все браузеры будут поддерживать webtransport. Есть какое то готовое решение для подписок через websocket или только придумывать свой протокол\реализацию обмена?
grpc-web нормально поддерживает service-side streams (нужно только с реконнектами разобраться, из коробки не работает и нужно самому накостылить обработчик).
Для задач веб-интерфейса этого обычно достаточно.
Через long polling?
Если fetch, не умирающий по таймауту, можно назвать long polling, то он.
Но long polling, емнип, подразумевает, что коннект через некоторое время рвется, а тут дисконнект только если со связью проблема.

Примерно вот такое. Мы раз в 2 минуты кидаем пустое сообщение на всякий случай. А так оно в принципе и без "пингов" висит и не отваливается. Но на nginx/envoy надо правильно таймауты накрутить.
Для js/ts и grpc-web в частности лучше использовать библиотеку https://github.com/timostamm/protobuf-ts
Она гораздо более удобна для работы и генерит натуральный ts код (а не js с тайпингами)
Про nginx и http2 чушь написана. Нормально он несекурный http2 переваривает.
Можно пример с connection upgrade, чтобы не получить "Received HTTP/0.9 when not allowed"?
Например, в Postman все еще нельзя загрузить proto файл и получить предзаполненные поля.
Сейчас это не так. В postman можно загрузить proto файл
https://learning.postman.com/docs/sending-requests/grpc/using-service-definition/
gRPC передает данные в бинарной форме, выигрыш по объему передаваемых данных 50-80% экономии трафика
Учтено ли здесь, что практически весь plaintext трафик rest/graphql/etc проходит через gzip? Сколько останется процентов, если его учесть?
А кто запрещает использовать компрессию и для HTTP/2 траффика? На gRPC не проверял, а на Kafka при lz4 компрессии protobuf выигрывает у JSON на небольших пакетах более чем в два раза. А вот если вломить пакет из 10 тыс. записей, то выигрыш сразу падает до 20%.
Никто не запрещает, но бинарные данные сжимаются сильно хуже текста, так что выигрыш в 50-80% из статьи это сравнение plaintext и сжатых данных. Выигрыш в объеме передаваемых данных у gRPC и аналогичных протоколов все же есть, но не такой драматический, как пишут в абсолютно всех статьях по gRPC при его сравнении с json
Вы точно прочитали, то что я написал? Или ограничились только первым предложением?
Прочитал, да, в принципе все верно, вопрос тут больше в типе пакета и объеме данных, когда мы говорим про выигрыш в 2+ раза - это скорее небольшой по размеру пакет (или очень разнородный пакет, т.е. данные, которые слабо поддаются сжатию)?
Для проверки с o1-preview написал скриптик, который гоняет разное количество разных по формату пакетов через protobuf и json с lz4 компрессией и получил в качестве результата те же 10-50% выигрыша у protobuf (меньше пакетов - больше выигрыш у бинарного формата, разумеется).

Не спец в python и тем более в реализации protobuf, но изъянов на беглый взгляд не обнаружил, можете посмотреть репозиторий.
В контексте web-разработки (а в статье упоминается она) пакетов обычно не так много, и они большие (десятки килобайт в среднем) и жмутся хорошо. Приводить 50-80% экономии трафика без сжатия на таких данных считаю некорректным
выигрыш в 2+ раза - это скорее небольшой по размеру пакет
А я писал: "на небольших пакетах более чем в два раза". Вы это повторно не увидели?
Не спец в python
Но на proto то можно было посмотреть, раз именно его обсуждаем? Бинарный protobuf экономит место для чисел, но уж никак не для строк. А в репозитории по ссылке его старательно грузят преимущественно строками, на которых по определению заметной разницы между бинарным и текстовым форматом быть не может.
А если посмотреть, например, сюда, то получаем уже числа близкие к приведенной мной статистике по топикам Кафки. Если еще учесть, что текстовой информации у меня очень мало, а преимущественно - числа с фиксированной десятичной точкой и перечисления (то есть целые числа с точки зрения protobuf), то выигрыш более чем в два раза на небольших пакетах оказывается вполне ожидаем.
В контексте web-разработки
В контексте применимости RPC, пакеты могут любыми. С точки зрения скорости прохождения сообщений (реакции системы), они наоборот должны быть маленькими.
Даже в web-разработке для меня странно гонять десятки килобайт в одном запросе. Это же на один-два порядка хуже время реакции на одно сообщение в сотню байт. Для примера, в Kafka по умолчанию max.in.flight.requests.per.connection = 5. То есть сжимаемый пакет содержит не более пяти сообщений.
К вашему комментарию нет никаких вопросов, на ваших данных все именно так, на числах с плавающей точкой тем более.
В моей сфере (интернет-магазины) типовое сообщение это на 90% текстовая информация и даже небольшой блок на сайте с картинками вполне может весить больше килобайта, а страница каталога с двумя десятками товаров больше 10 килобайт - возможно, у меня здесь профдеформация и для других систем (биржи акций, например) действительно можно слать очень небольшие пакеты из чисел.
Я ни в коем случае не спорю с тем, какого сжатия с protobuf можно добиться на определенных данных, но безаппеляционно заявлять про 50-80% экономии трафика на gRPC по сравнению с REST - это большое лукавство.
безаппеляционно заявлять про 50-80% экономии трафика на gRPC по сравнению с REST - это большое лукавство
Бритва Хэнлона. Это, скорее, ошибка, чем лукавство, так как не указано было, что речь идет исключительно о несжатых данных. В случае компрессии выигрыш 10-60%, в зависимости от количества бинарных данных и размеров пакета. Что, впрочем, тоже не мало.
gRPC по сравнению с REST
Protobuf по сравнению с JSON. Нужно отделять мух от котлет. gRPC не обязан использовать именно protobuf. Все же потоковый gRPC (HTTP/2) дает заметные преимущества перед REST в некоторых сценариях использования. Например, сервис прогнозируемых курсов валют на активном двунаправленном потоковом gRCP в локальной сети вполне может давать ответ на запрос за 1 мс. На REST такого достигнуть мало реально.
У нас контракты каждого сервиса живут в отдельном проекте. При сборке собираются пакеты: npm для front-end, nuget для backend, py для тестов. Плюс генерируется документация на контракт (html). Всё через ptotoc, в рамках ci. И всё это добро пушится в nexus. Front-end общается с бэком по gRPC. Полёт нормальный.
В постмане актуальной версии отлично работает подгрузка контрактов как через протофайлы так и через рефлексию. Аналогично с автозаполнением для запросов.
gRPC: проблемы и решения при переходе с REST