Архитектура микросервисов широко распространена в современном программировании. Благодаря этой архитектуре разработчики смогут самостоятельно разрабатывать сервисы и управлять ими. Однако очень важно выбрать правильный протокол для эффективного взаимодействия между микросервисами. Здесь протокол gRPC (Google Remote Treatment Call) выделяется своей высокой эффективностью и скоростью. В этой статье мы предоставим подробную информацию о RPC и gRPC, рассмотрим преимущества gRPC в архитектурах микросервисов и продемонстрируем их различия на примерах кода на языке программирования Go.
RPC это что?
Удаленный вызов процедур (RPC) — это протокол, который позволяет одному компьютеру выполнять вызов процедуры на другом компьютере. RPC позволяет разработчикам обмениваться данными между службами по сети. Этот протокол упрощает программистам вызов удаленных служб, поскольку они могут действовать так, как если бы они вызывали локальные процедуры.
RPC был первоначально разработан в 1980-х годах и широко используется в программировании для взаимодействия между сервисами. В традиционных системах RPC данные часто передаются в формате JSON или XML. Хотя эти форматы удобны для передачи данных, процесс их обработки и передачи по сети занимает много времени. Например, процесс передачи данных в формате JSON часто может занимать 100–200 миллисекунд. Это может вызвать проблемы в системах, работающих под высокой нагрузкой.
gRPC что это?
gRPC — это высокопроизводительная среда RPC, разработанная Google в 2015 году. gRPC использует формат Protobuf (буферы протокола), который позволяет передавать данные в двоичном формате. Данные, передаваемые в двоичном формате, намного быстрее и эффективнее, чем JSON или XML. Одним из основных преимуществ gRPC является скорость и эффективность, особенно в микросервисных архитектурах.
gRPC использует протокол HTTP/2, который позволяет отправлять несколько запросов одновременно. Это, в свою очередь, обеспечивает эффективное использование сетевых ресурсов. Основная цель gRPC — установление высокоскоростной и эффективной связи, обеспечивающей быстрый и надежный обмен данными между микросервисами.
Преимущество Protobuf
Преимущество Protobuf При использовании Protobuf процесс передачи данных происходит значительно быстрее. Например, процесс передачи данных в формате JSON или XML часто может занимать 100–200 миллисекунд. Однако с помощью Protobuf этот процесс можно сократить до 10–20 миллисекунд. Это особенно важно для систем, работающих под высокой нагрузкой.
Если мы посчитаем количество микросервисов, использующих gRPC и Protobuf вместе, мы сможем сэкономить 10 миллисекунд на каждый микросервис. Если у вас 100 микросервисов, это означает экономию времени в 1000 миллисекунд (т. е. 1 секунду). Если количество микросервисов увеличить, экономия времени будет более существенной. Да, вы можете сказать, что такое количество микросервисов встречается редко. Но если учесть, сколько прото-файлов пишется для каждого микросервиса, то это зависит еще и от количества методов grpc в микросервисах. Именно по этой причине Google создал gRPC на основе rpc. И микросервисы на языке программирования Go также в основном используют gRPC. gRPC используется не только в языке программирования go, но и в других языках программирования. Например: C++, Java, Python, Ruby, PHP, C#, JavaScript и другие языки программирования также используют gRPC. Его преимущество в том, что мы можем сгенерировать файл прототипа на нужном языке программирования. И если используется прото-файл, один микросервис проекта находится на Python, а другой — на Golang, мы можем сгенерировать Python-код прото-файла. Вы правы, что это можно сделать с помощью RPC, но это будет очень сложный процесс. Чтобы облегчить этот процесс, Google разработал gRPC. Но если вы попробуете RPC перед использованием gRPC, вы заметите разницу в коде и времени.
Преимущества gRPC
Скорость. При использовании gRPC данные передаются в двоичном формате, что увеличивает скорость. Данные, передаваемые в двоичном формате, намного быстрее и эффективнее, чем JSON или XML.
Эффективность. Процесс передачи данных с использованием Protobuf очень эффективен. При передаче данных с помощью Protobuf их размер уменьшается, что сокращает время передачи по сети.
Многоязычная поддержка: gRPC поддерживает несколько языков программирования, что позволяет программистам работать на своих любимых языках. gRPC можно использовать во многих языках программирования с помощью Protobuf.
Возможности потоковой передачи: возможности двусторонней потоковой передачи доступны с помощью gRPC, что облегчает обмен данными в реальном времени. Это особенно полезно при передаче больших объемов данных, например видео- или аудиопотоков.
Простая интеграция: gRPC обеспечивает легкую интеграцию с другими сервисами. Это позволяет разработчикам быстро создавать собственные сервисы и добавлять к ним новый функционал.
Безопасность: gRPC обеспечивает безопасную связь с использованием TLS (безопасность транспортного уровня). Это обеспечивает безопасность данных и усиливает защиту данных, передаваемых по сети.
Управление версиями: gRPC облегчает управление версиями, что упрощает обновление сервисов. Разработчики могут продолжать поддерживать старые версии и внедрять новые версии.
Простота тестирования. Службы gRPC легко тестировать, поскольку их интерфейс четко определен. Это позволяет разработчикам быстро тестировать сервисы.
Коды на изображениях ниже — это коды для создания службы, которая возвращает сообщение “Привет, Мир!”в RPC и gRPC.
Приоритеты кода
Скорость. При использовании gRPC данные передаются в двоичном формате, что увеличивает скорость. Данные, передаваемые в двоичном формате, намного быстрее и эффективнее, чем JSON или XML.
Эффективность. Процесс передачи данных с использованием Protobuf очень эффективен. При передаче данных с помощью Protobuf их размер уменьшается, что сокращает время передачи по сети.
Многоязычная поддержка: gRPC поддерживает несколько языков программирования, что позволяет программистам работать на своих любимых языках. gRPC можно использовать во многих языках программирования с помощью Protobuf.
Краткое содержание
Скорость и эффективность gRPC в архитектуре микросервисов позволяют разработчикам и компаниям предоставлять свои услуги более эффективно и быстро. Системы, разработанные с использованием gRPC и Protobuf, более эффективны и быстрее, чем традиционные системы RPC. Это особенно важно для систем, работающих под высокой нагрузкой. Многоязычная поддержка gRPC и возможности простой интеграции делают его очень полезным инструментом в современном программировании. Эту статью написал Вахобов Шахбоз, разработчик Golang. Приносим извинения за возможные неудобства. И мы просим вас обязательно сообщить об этом.
Комментарии (25)
Farongy
25.10.2024 10:28Скорость. При использовании gRPC данные передаются в двоичном формате, что увеличивает скорость. Данные, передаваемые в двоичном формате, намного быстрее и эффективнее, чем JSON или XML.
Это что значит? JSON или XML буквами передаются что ли?
kruslan
25.10.2024 10:28Толсто ((( Понимаете-же, что речь о бинарном формате vs текстовом? Или gzip (условно) не используете никогда и нигде?
qwzx
25.10.2024 10:28Вот и появилось поколение, которое не отличает текстовый формат передаваемых данных со своей разметкой (которую надо парсить) и текстовым представлением отдельных значений передаваемых параметров (которые надо конвертировать) от двоичного формата, для которого не нужен парсинг и даже может быть совсем не нужна конвертация типов.
Farongy
25.10.2024 10:28Каким образом необходимость парсинга влияет на передачу данных по сети? Физика как-то меняется?
Hrodvitnir
25.10.2024 10:28Скорость перевода данных в текст и обратно влияет на скорость передачи данных
vic_1
25.10.2024 10:28В контексте микросервисов тема не раскрыта. Как вы собираетесь шарить idl между сервисами?
Catmengi
25.10.2024 10:28Как вы думаете помогли-бы в микросервих rpc без idl? Условно есть функция на сервере которая имеет имя и аргументы, а вся обработка вызова, упаковка - распаковка аргументов и результата вынесена в рантайм
UnclShura
25.10.2024 10:28Proto создает либо огромные проблемы с читаемостью (goto definition показывает сгенерированный класс, который читать невозможно) либо проблемы с межьязыкоровой совместимостью когда proto создается динамически по исходникам. Он конечно быстрый и все такое, но неудобный.
AMDmi3
25.10.2024 10:28goto definition показывает сгенерированный класс, который читать невозможно
Зачем читать сгенерированный код? К протобуфам можно и нужно относиться как к POD.
либо проблемы с межьязыкоровой совместимостью когда proto создается динамически по исходникам
Зачем proto генерить по исходникам? По исходникам чего, вообще, и как вы это себе представляете? Не по исходникам же типов потому что типы генерируют сами протобуфы. Потом, откуда будут браться номера полей? Или при удалении поля едет совместимость?
Нет, .proto всегда single source of truth, это из него все генерятся. Да и независимо от того откуда взялся.proto, откуда взяться проблемам межьязыковой совместимости если именно и хон и решает?
pkokoshnikov
25.10.2024 10:28Тема не раскрыта. Утверждение что передача json занимает 200 мс, а protobuf 20 мс нужно проверить. Напишите хотя бы простейший перф тест.
kitchip
25.10.2024 10:28Как будто сводку от chatGPT прочитал ... . Одна вода
4wards1
25.10.2024 10:28Судя по "gRPC (Google Remote Treatment Call)", это и есть генерация от ChatGPT, причём невычитанная. Treatment, procedure - какая разница, правда?
mivlad
25.10.2024 10:28Вот как раз такую ошибку скорее человек бы допустил. ChatGPT контекст понимает и рядом с gRPC вряд ли станет переводить "процедура" как treatment. А вот кожаные мешки запросто переводят "сброшенные переменные" как unseated variables (не шучу, сам видел).
zmiik
25.10.2024 10:28Ещё можно сказать, что grpc хорош для случаев взаимодействия 1 к 1. А брокеры вроде Кафки и реббита для бродкастинга. Часто возникают задачи обработки одного события в множестве сервисов - пилить grpc в каждом - ад. Но как взаимодействие 1 к 1 grpc просто бескомпромиссный вариант.
zyaleniyeg
25.10.2024 10:28Недавно дебажили проблему на стыке микросервисов на gRpc, очень весело, в ответ иногда приходит null и делай что хочешь, проблема где то в сишных исходниках
C4ET4uK
25.10.2024 10:28Все-равно узкое место - это база. А дебажить json намного проще чем бинарный формат. nuff said. Понятно что где-то в верхней части кривой Шипелёва и на не такое пойдешь для выжимания последних крупиц перформанса, но чаще всего в этом нет необходимости.
Sipaha
25.10.2024 10:28JSON с быстрым сжатием на lz4 покажет похожие цифры скорости и объема трафика. Плюс есть и бинарные форматы для сериализации json'а (но мои эксперименты с ними показали те же цифры что и обычный JSON с сжатием).
breninsul
25.10.2024 10:28Не оговорены минусы:
1)Отсутствие возможности передать null
2)Тут зависит от экосистемы, но для java/kotlin плагины гугла генерируют весьма и весьма своеобразные DTO, с которыми работать крайне многословно
VladimirFarshatov
25.10.2024 10:28Выросло поколение не понимающее, что сетевой овкрхед только растёт от одной "серебряной пули" К следующей.
Напомню, что всё начинается с презентационного уровня клиента, где сообщение кодируется в формат grpc, bison, json, XML или куда ещё из внутренних структур клиента. Маппинг неизбежен.
Далее это разбивается на пакеты и уходит в сеть, обрамляясь описателями каждого следующего уровня. Да, да, с перекладываением тела пакета из буфера в буфер.
Сервер, принимая пакеты, проводит обратную работу, а дополнительно сборку сообщения из пакетов.
А далее.. Обратно раскодируем XML, json, grpc, bson в тот вид, который может обработать хендлер сервера..
И всё это зрятраты и оверхед. Можно оставить один сетевой оверхед и передавать бинарник, ровно такой который понимает вызов хендлера, кладя его напрямую на его стек. Достаточно вспомнить старые добрые времена 80-х..)
Ну и за транзакционную стойкость микро сервисной архитектуры.. Эх, молодо-зелено..)
prog_f130
25.10.2024 10:28Использую на проекте под нодой+nest.js где один из сервисов выступает фасадом. Чем понравилась связка protobuf + grpc конкретно на этом стеке - это возможность создавать контракты. Написал контракт - он скомпилировался в typescript интерфейсы, которые обязательны к реализации на других сервисах при использовании соответствующих декораторов.
Если бы не одно но: любой не скалярный тип становится опциональным полем + не подразумевается отправка пустых массивов.
Neruba
25.10.2024 10:28Странная математика. Было 100мс стало 10мс значит (по статье) разница 10 мс. Как? 90мс разница
mendler
но как минус имеем создание нового канала на каждое сообщение, почему бы не использовать Protobuf через WebSocket?
gudvinr
Есть стримы любой направленности, не обязательно создавать новый канал
so-mironov
HTTP/2 поддерживает постоянные соединения, так что WebSocket не требуется.