gRPC (gRPC Remote Procedure Calls) — это высокопроизводительный фреймворк от Google. Если REST API отлично подходит для общения браузера с сервером, то gRPC — круто подходит для общения микросервисов между собой (Server-to-Server).
Почему микросервисы отказываются от REST?
- Скорость сериализации (JSON vs Protobuf): REST гоняет данные в текстовом JSON. Парсинг скобочек и кавычек съедает кучу CPU. gRPC использует Protocol Buffers (Protobuf) — бинарный формат данных, который сериализуется и десериализуется в разы быстрее.
- Сетевая эффективность (HTTP/1.1 vs HTTP/2): Классический REST работает поверх HTTP/1.1. gRPC жестко завязан на HTTP/2. Главная фишка HTTP/2 — это мультиплексирование. Вместо того чтобы открывать новое TCP-соединение на каждый запрос, gRPC гоняет тысячи параллельных вызовов через одно соединение без блокировок.
- Строгая типизация (Контракты): В REST легко отправить строку вместо числа и уронить чужой сервис. В gRPC контракт (схема данных) описывается заранее в
файле. Из этого файла автоматически генерируется готовый код (заглушки) для клиентов и серверов на Go, Java, Python и C++..proto - Bidirectional Streaming (Потоки): REST умеет только «запрос-ответ». gRPC умеет гонять непрерывные потоки данных в обе стороны одновременно (например, для передачи видео или чатов).
Как выглядит контракт (Protobuf)
syntax = "proto3";
package calculator;
// Определение структуры запроса
message AddRequest {
double a = 1; // ВАЖНО: 1 - это не значение по умолчанию!
double b = 2; // Это уникальный бинарный ТЕГ (ID) поля.
}
// Определение ответа
message AddResponse {
double result = 1;
}
// Описание самого сервиса и его методов
service Calculator {
rpc Add (AddRequest) returns (AddResponse);
}
Ловушка: В коде выше цифры и = 1 — это не дефолтные значения переменных! Это уникальные числовые теги (ID) для бинарной сериализации. Благодаря им Protobuf не передает по сети длинные строковые имена полей (как ключи в JSON), а шлет только крошечные числа, экономя трафик.= 2
Минусы gRPC
- Не читается глазами: Если ты перехватишь трафик gRPC (например, в Charles или Wireshark), ты увидишь бинарную кашу. Без исходного
файла данные невозможно расшифровать..proto - Плохая поддержка в браузере: Браузеры не дают разработчикам полного контроля над фреймами HTTP/2. Поэтому ты не можешь просто взять и дернуть gRPC ручку из React/Vue приложения (как ты делаешь
для REST). Приходится использовать костыли вроде библиотеки gRPC-Web или ставить перед фронтендом Envoy Proxy для транскодинга gRPC в REST.fetch()
Кейс из прода: Когда gRPC оказывается медленнее REST?
Многие команды внедряют gRPC, ожидают космических скоростей, а в итоге получают тайминги хуже, чем на старом REST. Почему так происходит? Ответ кроется в Сжатии (Compression).
- В классическом REST (через Nginx/браузеры) сжатие Gzip почти всегда включено по умолчанию.
- В gRPC сжатие ВЫКЛЮЧЕНО по умолчанию. Это осознанное проектное решение.
gRPC создавался для быстрых внутренних сетей дата-центров (10-40 Gbit/s). Если микросервисы гоняют друг другу миллионы мелких запросов (по 100 байт), тратить такты CPU на их сжатие — бессмысленно, это только замедлит систему (CPU станет узким местом). Но если ты передаешь мегабайтные списки или файлы, не сжатый Protobuf будет лететь по сети дольше, чем сжатый JSON.
Подробности этого случая можешь прочитать в посте.
Главный вывод: Protobuf (сериализация) и Gzip (сжатие) — это разные уровни оптимизации. Если ты передаешь через gRPC большие объемы данных (или общаешься через медленный интернет), обязательно включай сжатие в настройках gRPC-клиента. Иначе твой gRPC проиграе REST-у просто из-за размера пакетов.