gRPC
Фреймворк удалённого вызова процедур от Google: бинарный формат Protocol Buffers поверх HTTP/2, строгий контракт и генерация клиента из .proto-файла.
Что такое gRPC
gRPC — фреймворк удалённого вызова процедур (RPC, Remote Procedure Call). Идея RPC в том, что вызов чужого сервиса выглядит в коде как вызов обычной функции: клиент пишет client.GetUser(id), а сеть, сериализация и разбор ответа скрыты в сгенерированном коде.
Три опоры gRPC: контракт в файле .proto, бинарная сериализация Protocol Buffers и транспорт HTTP/2. Разработан в Google, открыт и развивается в CNCF; расшифровка названия — рекурсивная шутка «gRPC Remote Procedure Calls».
Главное отличие от REST: контракт не описан в документации, а задан машиночитаемо и проверяется компилятором. Опечатка в имени поля ломает сборку, а не всплывает в проде.
Контракт: файл .proto
syntax = "proto3";
package users.v1;
service UserService {
rpc GetUser (GetUserRequest) returns (User);
rpc ListUsers (ListUsersRequest) returns (stream User);
}
message GetUserRequest {
string user_id = 1;
}
message User {
string user_id = 1;
string email = 2;
int32 created_at = 3;
}
Компилятор protoc собирает из этого файла и клиента, и заготовку сервера — для Go, Python, Java, C++, Node.js и других языков. Обе стороны используют один .proto, поэтому разъехаться не могут.
Числа = 1, = 2 — теги полей: именно они летят по сети вместо имён, что и делает формат компактным. Отсюда правило совместимости: тег занятого поля нельзя переиспользовать, а новые поля добавляют с новыми номерами — старый клиент их просто проигнорирует.
Четыре типа вызовов
| Тип | Как работает | Пример |
|---|---|---|
| Unary | запрос → ответ | получить пользователя |
| Server streaming | запрос → поток ответов | подписка на события, выдача токенов LLM |
| Client streaming | поток запросов → ответ | загрузка чанков аудио в ASR |
| Bidirectional | оба потока одновременно | голосовой диалог, чат |
Стриминг работает благодаря HTTP/2: в одном TCP-соединении живёт много независимых потоков, и ответ не обязан быть единственным. При этом соединение переиспользуется — без хендшейка на каждый запрос.
gRPC против REST
| gRPC | REST | |
|---|---|---|
| Формат | Protobuf (бинарь) | JSON (текст) |
| Транспорт | HTTP/2 | HTTP/1.1, HTTP/2 |
| Контракт | .proto, обязателен |
OpenAPI, по желанию |
| Из браузера | только через gRPC-Web и прокси | напрямую |
| Отладка curl | нет, нужен grpcurl |
да |
| Стриминг | встроенный, в обе стороны | обходные пути или WebSocket |
Практическое правило: наружу — REST, внутрь — gRPC. Публичный API должен открываться в браузере и читаться глазами; вызовы между микросервисами выигрывают от бинарного формата и мультиплексирования, а браузер там ни при чём.
Отладка и эксплуатация
# Список сервисов, если включена reflection
grpcurl -plaintext localhost:50051 list
# Вызов метода
grpcurl -plaintext -d '{"user_id": "42"}' \
localhost:50051 users.v1.UserService/GetUser
Ошибки передаются не HTTP-кодами, а собственными статусами: NOT_FOUND, INVALID_ARGUMENT, UNAVAILABLE, DEADLINE_EXCEEDED. У каждого вызова есть deadline — клиент задаёт предельное время, и оно передаётся дальше по цепочке вызовов.
Балансировка требует внимания: gRPC держит долгоживущее соединение, поэтому обычный L4-балансировщик распределит соединения, но не запросы, и вся нагрузка осядет на одной реплике. Нужен L7-прокси с поддержкой HTTP/2 или клиентская балансировка — в Kubernetes это решают через headless-сервис или service mesh.
Связанные термины
- API — общий контекст межсервисного взаимодействия
- REST API — альтернативный стиль и стандарт для публичных API
- Микросервисы и монолит — среда, где gRPC применяют чаще всего
- HTTP — HTTP/2 как транспорт gRPC
- WebSocket — другой способ двустороннего обмена
Готовы запустить GPU-задачу?
Запустить GPU-сервер