Web & API

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-сервер