gRPC — это технология удаленного вызова процедур, или Remote Procedure Call, предназначенная для взаимодействия между приложениями и сервисами. Она позволяет клиенту вызывать функцию на удаленном сервере почти так же, как обычную функцию внутри программы.
gRPC особенно часто используется в микросервисной архитектуре, где сервисы должны быстро и предсказуемо обмениваться данными. Вместо ручного описания большого количества HTTP-запросов разработчики создают формальный контракт, после чего инструменты gRPC генерируют часть клиентского и серверного кода.
Для описания сообщений и методов обычно применяется Protocol Buffers. Благодаря строгой типизации клиент и сервер заранее знают структуру запросов и ответов.
Что такое gRPC простыми словами
Представим два микросервиса: сервис заказов и сервис платежей. Сервис заказов должен проверить платеж.
В REST API он может сформировать HTTP-запрос к определенному URL, отправить JSON и обработать ответ. В gRPC разработчик описывает метод PaymentService.GetPaymentStatus и структуру данных, а затем вызывает этот удаленный метод через сгенерированный клиент.
Главная идея gRPC — превратить сетевое взаимодействие между сервисами в строго описанные удаленные вызовы методов.
Сеть при этом никуда не исчезает. Возможны timeout, недоступность сервиса и ошибки соединения, поэтому удаленный вызов нельзя считать полностью аналогичным локальной функции.
Для чего нужен gRPC
gRPC особенно полезен в системах с большим количеством внутренних сервисов и частыми вызовами между ними.
- взаимодействие микросервисов;
- высокочастотные внутренние API;
- строгие контракты между командами;
- обмен структурированными данными;
- генерация клиентских библиотек;
- двунаправленный Streaming;
- интеграция сервисов на разных языках;
- низкие накладные расходы на сериализацию;
- построение распределенных Backend-систем.
Что означает RPC
RPC расшифровывается как Remote Procedure Call — удаленный вызов процедуры.
Клиент вызывает метод, который физически выполняется на другом сервере или в другом процессе.
Например, код вызывает функцию GetUser, но фактически запрос отправляется по сети к user-service.
RPC скрывает часть сетевых деталей за интерфейсом метода, но разработчик все равно должен учитывать распределенную природу системы.
Как работает gRPC
Упрощенный процесс выглядит следующим образом.
- Разработчик описывает сервис и сообщения в .proto-файле.
- Из контракта генерируется клиентский и серверный код.
- Сервер реализует бизнес-логику методов.
- Клиент вызывает сгенерированный метод.
- gRPC сериализует данные и отправляет их по сети.
- Сервер выполняет метод.
- Ответ сериализуется и возвращается клиенту.
Что такое Protocol Buffers
Protocol Buffers, или Protobuf, — формат описания и сериализации структурированных данных, часто используемый вместе с gRPC.
Разработчик определяет типы сообщений и поля в .proto-файле.
message UserRequest {
int64 id = 1;
}
message UserResponse {
int64 id = 1;
string name = 2;
}После этого инструменты могут сгенерировать классы для работы с этими структурами в выбранном языке программирования.
Что такое .proto-файл
.proto — файл с формальным описанием сообщений и сервисов.
В нем определяются структуры данных, типы полей, методы и параметры.
Такой файл становится важной частью API-контракта между сервисами.
Его удобно хранить в Git и проверять через Code Review.
Описание сервиса в gRPC
Сервис может быть описан следующим образом.
service UserService {
rpc GetUser(UserRequest) returns (UserResponse);
}После генерации клиент получает метод GetUser, а сервер — интерфейс, который необходимо реализовать.
Это уменьшает количество ручного кода для сериализации и сетевого взаимодействия.
Строгая типизация gRPC
В gRPC структура сообщений заранее определяется контрактом.
Например, поле id имеет числовой тип, а name — строковый.
Если клиент пытается передать несовместимые данные, часть ошибок можно обнаружить еще на этапе разработки или компиляции.
Это особенно удобно в больших системах с несколькими командами.
gRPC и REST API
gRPC часто сравнивают с REST, поскольку оба подхода используются для взаимодействия сервисов.
| REST API | gRPC |
|---|---|
| Обычно строится вокруг ресурсов и URL | Строится вокруг методов сервисов |
| Часто использует JSON | Часто использует Protocol Buffers |
| Удобен для публичных API | Особенно удобен для внутренних сервисов |
| Легко проверяется стандартными HTTP-инструментами | Обычно требует gRPC-клиента или специализированного инструмента |
| Контракт может быть менее строгим | Контракт явно описывается в .proto |
Когда gRPC быстрее REST
gRPC может быть эффективнее в сценариях с большим количеством межсервисных вызовов благодаря компактному бинарному представлению данных и постоянным соединениям.
Но производительность зависит не только от протокола.
Медленный SQL-запрос, внешняя система или бизнес-логика могут занимать гораздо больше времени, чем сериализация сообщения.
Поэтому выбор gRPC должен основываться не только на желании получить максимальную скорость.
Что такое сериализация
Сериализация — преобразование объекта программы в формат, который можно сохранить или передать по сети.
В REST часто используется JSON. В gRPC сообщения обычно сериализуются через Protocol Buffers.
Бинарное представление обычно компактнее текстового JSON, но его сложнее прочитать человеку непосредственно в сетевом трафике.
gRPC и HTTP/2
gRPC использует возможности HTTP/2 для эффективного обмена данными.
Это позволяет поддерживать несколько параллельных запросов через одно соединение, Streaming и другие сетевые возможности.
Разработчику обычно не приходится вручную реализовывать низкоуровневое управление HTTP/2.
Multiplexing
Multiplexing позволяет передавать несколько независимых потоков через одно сетевое соединение.
Это уменьшает необходимость создавать отдельное соединение для каждого запроса.
В системах с большим количеством частых межсервисных вызовов такая модель может уменьшать сетевые накладные расходы.
Какие типы вызовов поддерживает gRPC
gRPC поддерживает несколько моделей взаимодействия.
| Тип | Принцип |
|---|---|
| Unary RPC | Один запрос и один ответ |
| Server Streaming | Один запрос и поток ответов |
| Client Streaming | Поток запросов и один ответ |
| Bidirectional Streaming | Обе стороны обмениваются потоками сообщений |
Что такое Unary RPC
Unary RPC — наиболее простой вариант.
Клиент отправляет один запрос и получает один ответ.
Например, сервис заказов запрашивает информацию об одном пользователе.
По модели взаимодействия такой вызов похож на обычный HTTP Request-Response.
Server Streaming
При Server Streaming клиент отправляет один запрос, а сервер возвращает последовательность сообщений.
Например, клиент запрашивает большой поток событий или результатов обработки.
Вместо формирования одного огромного ответа сервер передает данные постепенно.
Client Streaming
При Client Streaming клиент отправляет последовательность сообщений, после чего сервер возвращает итоговый ответ.
Например, клиент передает набор измерений или частей данных, а сервер после завершения потока формирует результат.
Это позволяет не собирать весь объем информации в одном большом запросе.
Bidirectional Streaming
Bidirectional Streaming позволяет клиенту и серверу независимо отправлять потоки сообщений в рамках одного соединения.
Такой механизм подходит для real-time взаимодействия, потоковой обработки и сложных двусторонних коммуникаций.
При этом Streaming значительно усложняет обработку ошибок, состояние соединений и масштабирование.
gRPC Streaming и WebSocket
gRPC Streaming и WebSocket могут использоваться для длительного двустороннего обмена, но относятся к разным моделям.
gRPC сохраняет типизированные методы и сообщения, а WebSocket предоставляет более общий двусторонний канал передачи данных.
Выбор зависит от клиента, инфраструктуры и требований приложения.
gRPC и GraphQL
gRPC и GraphQL решают разные задачи.
GraphQL часто используется между Frontend и Backend, когда клиенту нужна гибкость выбора данных.
gRPC особенно хорошо подходит для строгого и быстрого взаимодействия внутренних сервисов.
| GraphQL | gRPC |
|---|---|
| Клиент выбирает нужные поля | Методы и сообщения заранее определены |
| Ориентирован на гибкий API данных | Ориентирован на RPC-взаимодействие |
| Часто используется с Frontend | Часто используется между Backend-сервисами |
gRPC и Backend
Backend-сервисы могут предоставлять gRPC-интерфейс другим внутренним компонентам.
Например, order-service вызывает inventory-service для проверки остатка товара.
Для внешнего Frontend при этом может использоваться REST или GraphQL API.
Таким образом, один Backend способен иметь несколько типов интерфейсов для разных клиентов.
gRPC и Frontend
Обычный браузерный Frontend не всегда взаимодействует с gRPC так же напрямую, как внутренний Backend-сервис.
Поэтому между браузером и сервером могут использоваться дополнительные механизмы или адаптированные варианты RPC-взаимодействия.
Для публичных веб-интерфейсов REST и GraphQL зачастую проще с точки зрения совместимости и диагностики.
gRPC и микросервисы
Микросервисная архитектура является одним из основных сценариев использования gRPC.
Сервисы имеют четкие контракты и генерируемые клиенты, поэтому взаимодействие между командами становится более формализованным.
Например, payment-service публикует .proto-контракт. Order-service использует сгенерированный клиент и вызывает методы без ручной сборки JSON.
gRPC и Polyglot Architecture
В крупной системе сервисы могут быть написаны на разных языках программирования.
Один работает на Go, другой на Java, третий на Python.
Формальный .proto-контракт позволяет генерировать клиентский и серверный код для разных языков и поддерживать единый интерфейс.
Это облегчает межъязыковое взаимодействие.
Генерация кода
Одна из сильных сторон gRPC — автоматическая генерация Stub и серверных интерфейсов.
Разработчику не нужно вручную создавать модели запросов и сетевой клиент для каждого метода.
При изменении .proto соответствующий код можно пересоздать.
Важно включать процесс генерации в CI/CD или стандартный workflow команды.
Что такое Client Stub
Client Stub — сгенерированный клиентский объект, через который приложение вызывает удаленные методы.
С точки зрения разработчика вызов может выглядеть почти как обращение к обычной функции.
Stub выполняет сериализацию, передачу сообщения и получение ответа.
Но ошибки сети и deadline все равно должны обрабатываться отдельно.
Deadline в gRPC
Deadline определяет, до какого момента клиент готов ждать завершения вызова.
Если сервер не успел ответить вовремя, операция должна завершиться ошибкой вместо бесконечного ожидания.
Deadline особенно важен в микросервисах, поскольку один пользовательский запрос может последовательно вызывать множество сервисов.
У удаленного вызова должен быть ограниченный срок ожидания: сеть и зависимые сервисы могут быть недоступны.
Timeout и Deadline
Timeout задает продолжительность ожидания, а Deadline обычно представляет конкретный конечный момент времени.
Оба механизма служат общей цели — не позволять запросу зависнуть неопределенно долго.
В распределенных цепочках полезно передавать оставшийся Deadline следующим сервисам.
Retries в gRPC
Некоторые ошибки можно обрабатывать повторной попыткой.
Например, кратковременный сетевой сбой может исчезнуть при повторном вызове.
Но Retry безопасен не для каждой операции.
Если метод создает платеж или выполняет другое изменение, необходимо учитывать идемпотентность.
Идемпотентность gRPC-методов
Идемпотентный метод можно повторить без нежелательного повторения бизнес-результата.
Например, повторное чтение профиля пользователя не создает новый объект.
А повторная команда списания денег может привести к двойной операции, если сервер не имеет дополнительной защиты.
Поэтому автоматические retries следует проектировать вместе с семантикой методов.
gRPC Status Codes
gRPC использует набор собственных логических статусов для описания результата RPC-вызова.
Они позволяют различать недоступность сервиса, некорректные аргументы, отсутствие прав и другие типы ошибок.
Клиент должен обрабатывать статусы осмысленно, а не превращать все проблемы в единую ошибку.
Обработка ошибок
Ошибки gRPC можно разделить на технические и бизнес-ошибки.
Например, недоступность сервиса является инфраструктурной проблемой, а недостаточный остаток товара — бизнес-состоянием.
Хороший контракт должен позволять клиенту различать эти ситуации и выбирать правильное поведение.
gRPC Metadata
Metadata позволяет передавать дополнительную информацию вместе с RPC-вызовом.
Например, через Metadata могут передаваться данные аутентификации, Trace ID или другие служебные параметры.
Metadata не должна использоваться как случайное хранилище бизнес-данных, которые логично описать в самом сообщении.
gRPC и аутентификация
Вызовы между сервисами должны иметь понятную модель доверия.
Для аутентификации могут применяться токены, TLS-сертификаты и инфраструктурные механизмы Service Mesh.
Внутренняя сеть не должна автоматически считаться полностью доверенной.
Особенно это важно для сервисов, работающих с платежами, персональными данными или административными операциями.
gRPC и TLS
TLS защищает сетевое соединение от чтения и изменения данных третьими сторонами.
В production межсервисный трафик часто должен передаваться через защищенные соединения.
При Mutual TLS обе стороны дополнительно подтверждают свою идентичность.
gRPC и mTLS
mTLS особенно полезен в микросервисной инфраструктуре.
Order-service может криптографически подтвердить, что взаимодействует именно с payment-service.
Управлять mTLS вручную между десятками сервисов сложно, поэтому эту функцию часто автоматизирует Service Mesh.
gRPC и Service Mesh
Service Mesh хорошо сочетается с gRPC.
Istio и другие решения могут управлять mTLS, маршрутизацией, метриками, retries и политиками межсервисного трафика.
gRPC при этом определяет контракт приложения, а Service Mesh управляет сетевой доставкой запросов.
gRPC и Istio
Istio может видеть gRPC-трафик и применять к нему сетевые политики.
Например, можно включить mTLS между сервисами, собирать метрики и управлять направлением трафика на разные версии Backend.
Но бизнес-методы и структуры Protobuf остаются частью приложения, а не Service Mesh.
gRPC и Load Balancing
В production один gRPC-сервис обычно имеет несколько экземпляров.
Запросы необходимо распределять между ними.
Балансировка может выполняться различными инфраструктурными уровнями в зависимости от архитектуры.
При длительных HTTP/2-соединениях важно учитывать, как именно выбранное решение распределяет соединения и отдельные RPC.
gRPC и Kubernetes
gRPC-сервисы часто запускаются в Kubernetes.
Deployment поддерживает необходимое количество pod, а Service предоставляет стабильную точку доступа.
При масштабировании важно корректно настроить readiness probes и завершение соединений во время rolling update.
Service Mesh может добавлять расширенную маршрутизацию поверх Kubernetes.
Readiness и gRPC
Сервис не должен получать production-трафик до полной готовности.
Например, процесс уже запущен, но приложение еще устанавливает соединение с базой данных.
Readiness-проверка помогает исключить такой экземпляр из балансировки до момента готовности.
Graceful Shutdown
При обновлении контейнера приложение должно корректно завершать активные RPC.
Если процесс мгновенно остановить, текущие запросы или Streaming-соединения могут оборваться.
Graceful Shutdown дает сервису время прекратить прием новых вызовов и завершить уже начатые операции.
gRPC и Docker
gRPC-сервис можно упаковать в Docker image так же, как любой Backend.
Image содержит приложение и необходимые зависимости.
Затем сервис запускается в Docker Compose, Kubernetes или другой контейнерной среде.
gRPC и Docker Compose
В development несколько gRPC-сервисов удобно запускать через Docker Compose.
Например, order-service, payment-service и PostgreSQL описываются в одном compose.yaml.
Сервисы обращаются друг к другу по внутренним DNS-именам Docker Network.
gRPC и API Gateway
Внешние клиенты могут не работать с внутренним gRPC API напрямую.
В таком случае API Gateway или специальный Backend-слой преобразует внешний REST или GraphQL запрос во внутренние gRPC-вызовы.
Это позволяет использовать gRPC внутри инфраструктуры, сохраняя удобный публичный API для партнеров и браузеров.
gRPC Gateway
Иногда архитектура предусматривает автоматизированное представление части gRPC-сервисов через HTTP API.
Так можно поддерживать единый .proto-контракт для Backend и одновременно предоставить более традиционный интерфейс внешним клиентам.
При этом необходимо внимательно контролировать различия между RPC и REST-моделями.
gRPC и Webhook
gRPC и Webhook предназначены для разных сценариев.
gRPC обычно используется для прямого взаимодействия сервисов, когда клиент инициирует вызов.
Webhook применяется для отправки события другой системе при наступлении определенного события.
В одной архитектуре они могут использоваться совместно.
gRPC и Message Queue
gRPC является синхронным или потоковым способом прямого взаимодействия, а Message Queue предоставляет асинхронную передачу сообщений через брокер.
| gRPC | Message Queue |
|---|---|
| Прямой вызов сервиса | Передача через брокер |
| Клиент часто ожидает результат | Отправитель может не ждать обработку |
| Подходит для запрос-ответ | Подходит для событий и фоновых задач |
Выбор зависит от того, должен ли клиент получить результат немедленно.
gRPC и Event-driven Architecture
В Event-driven Architecture для бизнес-событий обычно используют брокеры сообщений или Streaming-платформы.
gRPC может применяться рядом с ними для синхронных запросов.
Например, order-service через gRPC проверяет остаток товара, а после создания заказа публикует событие OrderCreated в Message Broker.
gRPC и CI/CD
.proto-контракты должны проверяться через CI так же, как программный код.
Pipeline может выполнять генерацию кода, компиляцию, автоматические тесты и проверку несовместимых изменений.
Это особенно важно, если одним сервисом пользуются десятки клиентов.
gRPC и GitLab
Исходный код и .proto-файлы можно хранить в GitLab.
Merge Request позволяет проверить изменение контракта до объединения.
GitLab CI/CD может генерировать клиентские библиотеки, выполнять тесты и собирать Docker image сервиса.
Версионирование gRPC API
gRPC-контракт развивается вместе с системой.
При изменениях необходимо учитывать существующих клиентов и правила совместимости Protocol Buffers.
Небезопасное изменение номера или смысла поля способно привести к неправильной интерпретации сообщений.
Поэтому Schema Evolution должна быть частью процесса разработки.
Совместимость Protobuf
При развитии сообщений следует сохранять стабильность существующих полей и аккуратно добавлять новые.
Удаленное поле не следует бездумно заменять новым значением с тем же числовым идентификатором.
Старые и новые версии сервисов могут некоторое время работать одновременно, особенно при Rolling Update.
Backward Compatibility
Обратная совместимость позволяет новому серверу продолжать работать со старыми клиентами.
Это особенно важно в микросервисах, где невозможно обновить все сервисы строго одновременно.
Добавление нового необязательного поля обычно проще сделать совместимым, чем изменение смысла существующего.
gRPC и тестирование
gRPC-сервисы можно проверять на разных уровнях.
| Тип теста | Что проверяет |
|---|---|
| Unit Test | Бизнес-логику метода |
| Contract Test | Соответствие клиента и сервера контракту |
| Integration Test | Работу gRPC и зависимостей |
| E2E | Полный сценарий через несколько сервисов |
Contract Testing
Строгий .proto-контракт уменьшает часть проблем интеграции, но не гарантирует совпадение бизнес-семантики.
Например, тип поля остался прежним, но команда изменила значение или правила его заполнения.
Contract Tests и интеграционные проверки помогают обнаруживать подобные расхождения до production.
gRPC и Observability
Для эксплуатации gRPC необходимо отслеживать количество вызовов, ошибки и latency.
Если все методы проходят через один сетевой порт, мониторинг только TCP-соединений недостаточен.
Метрики следует разделять по сервисам и RPC-методам.
Основные метрики gRPC
| Метрика | Что показывает |
|---|---|
| Request Rate | Количество RPC-вызовов |
| Error Rate | Долю неуспешных вызовов |
| Latency | Время выполнения RPC |
| Active Streams | Количество активных потоковых соединений |
| Message Size | Размер передаваемых сообщений |
gRPC и OpenTelemetry
OpenTelemetry хорошо подходит для распределенной трассировки gRPC-вызовов.
Trace может начинаться в API Gateway, проходить через order-service и далее через gRPC в inventory-service и payment-service.
Так инженер видит, какой именно RPC создает задержку или ошибку.
gRPC и Prometheus
Приложение может экспортировать метрики gRPC для Prometheus.
Например, количество вызовов GetUser, Error Rate и распределение latency.
Grafana затем отображает эти показатели на дашбордах.
Логирование gRPC
Логи должны содержать имя сервиса, метод, Trace ID, длительность и результат вызова.
Не следует без необходимости записывать полное содержимое сообщений: они могут содержать персональные данные, токены или другую чувствительную информацию.
Для диагностики полезнее структурированные технические поля.
gRPC Interceptors
Interceptor — механизм, который позволяет выполнять общую логику до или после RPC-вызова.
Например, через Interceptor можно реализовать логирование, проверку токена, метрики и трассировку.
Это уменьшает дублирование технического кода в каждом методе сервиса.
gRPC и Middleware
Interceptors выполняют роль, похожую на Middleware в веб-фреймворках.
Запрос проходит через общий слой обработки перед попаданием в бизнес-метод.
В этом месте удобно размещать инфраструктурные функции, но не стоит переносить туда сложную бизнес-логику.
Health Checking
Для оркестрации важно понимать, готов ли gRPC-сервис принимать запросы.
Health Check может использоваться Load Balancer, Kubernetes или системой мониторинга.
Проверка должна отражать реальную готовность приложения, а не только наличие запущенного процесса.
Reflection
Reflection позволяет специализированным инструментам исследовать доступные gRPC-сервисы и методы во время работы.
Это удобно в development и при диагностике.
В production доступность такой возможности следует оценивать с учетом требований безопасности.
Отладка gRPC
Бинарные сообщения сложнее читать вручную, чем JSON.
Поэтому для тестирования используются специализированные gRPC-клиенты, Reflection, логи и tracing.
Наличие качественной Observability особенно важно в системах с большим количеством RPC-связей.
Безопасность gRPC
gRPC-сервис является сетевым API и требует тех же базовых принципов безопасности, что и другие Backend-интерфейсы.
- использовать TLS или mTLS;
- проверять аутентификацию;
- проверять права доступа;
- валидировать входные данные;
- ограничивать размер сообщений;
- задавать Deadline;
- не хранить секреты в коде;
- вести аудит критичных методов;
- защищать административные RPC.
Ограничение размера сообщений
Очень большие RPC-сообщения могут создавать высокую нагрузку на память и сеть.
Если необходимо передавать гигантские файлы, иногда лучше использовать объектное хранилище и передавать через gRPC только ссылку или метаданные.
Для потоковых данных можно рассмотреть Streaming.
gRPC и большие файлы
Технически данные можно передавать через RPC, но это не всегда лучший архитектурный выбор.
Например, видеофайл размером несколько гигабайт удобнее хранить в специализированном объектном хранилище.
gRPC при этом управляет метаданными и процессом загрузки.
Преимущества gRPC
- строгий типизированный контракт;
- генерация клиентского и серверного кода;
- компактная сериализация;
- удобство взаимодействия микросервисов;
- поддержка нескольких языков программирования;
- Unary и Streaming вызовы;
- хорошая производительность;
- совместимость с Observability и Service Mesh.
Недостатки gRPC
- сложнее ручная отладка бинарного трафика;
- не всегда удобен непосредственно для браузерных клиентов;
- требует управления .proto-контрактами;
- команде нужно понимать особенности RPC;
- Streaming усложняет инфраструктуру;
- публичным партнерам REST API иногда проще использовать;
- ошибки сети легко недооценить из-за внешнего сходства вызова с локальной функцией.
Типичные ошибки при использовании gRPC
- Не задавать Deadline для RPC.
- Автоматически повторять неидемпотентные операции.
- Не учитывать совместимость .proto.
- Использовать gRPC для любого публичного API без оценки клиентов.
- Передавать огромные сообщения без необходимости.
- Не собирать метрики по отдельным RPC-методам.
- Не реализовывать Graceful Shutdown.
- Считать внутреннюю сеть безопасной по умолчанию.
- Игнорировать ошибки частичной недоступности зависимостей.
- Создавать слишком тесно связанные сервисные контракты.
Как спроектировать хороший gRPC API
Шаг 1. Определить границы сервиса
Методы должны отражать понятную бизнес-ответственность конкретного сервиса.
Шаг 2. Спроектировать .proto
Сообщения и методы нужно делать понятными, стабильными и пригодными для расширения.
Шаг 3. Продумать совместимость
Контракт должен позволять независимо обновлять клиент и сервер.
Шаг 4. Настроить Deadline
Удаленные вызовы не должны ждать бесконечно.
Шаг 5. Определить политику Retry
Нужно учитывать идемпотентность каждого метода.
Шаг 6. Добавить безопасность
TLS, аутентификация и авторизация должны проектироваться до production.
Шаг 7. Добавить Observability
Метрики, логи и traces должны разделяться по методам.
Шаг 8. Автоматизировать проверку контракта
Изменения .proto должны проходить CI и Code Review.
Практический пример
Компания развивает интернет-магазин из нескольких микросервисов. Order-service при оформлении заказа должен проверить наличие товара, рассчитать доставку и создать платеж.
Внутренние сервисы используют gRPC. Inventory-service предоставляет метод CheckStock, payment-service — CreatePayment, а delivery-service — CalculateDelivery.
Контракты описаны в .proto и хранятся в GitLab. CI проверяет изменения и генерирует клиентские библиотеки.
Order-service вызывает необходимые методы через сгенерированные Stub. Для каждого RPC установлен Deadline.
Повторные попытки разрешены только для операций, где это безопасно. CreatePayment дополнительно использует идентификатор операции, чтобы предотвратить двойное списание.
Сервисы работают в Kubernetes. Istio обеспечивает mTLS и сетевые метрики между workload.
OpenTelemetry создает Trace пользовательского заказа и показывает длительность каждого gRPC-вызова.
Для внешнего мобильного приложения компания при этом оставляет обычный HTTP API через API Gateway, поскольку внутренние детали gRPC клиенту не нужны.
gRPC для бизнеса
gRPC особенно полезен компаниям с крупной микросервисной платформой, где множество команд регулярно создают межсервисные интеграции.
Строгий контракт уменьшает количество расхождений между клиентами и серверами, а генерация кода ускоряет разработку.
Компактное представление данных и Streaming могут быть полезны в высоконагруженных системах.
При этом gRPC добавляет собственную сложность, поэтому для небольшого монолита или простого публичного API его преимущества могут не окупить затраты.
Когда нужен gRPC
- есть большое количество микросервисов;
- нужен строгий контракт между командами;
- сервисы написаны на разных языках;
- важны частые межсервисные вызовы;
- требуется Streaming;
- нужно генерировать клиентский код;
- REST создает избыточные накладные расходы;
- инфраструктура уже использует Kubernetes и Service Mesh.
Когда gRPC может быть избыточным
Для небольшого сайта или простого Backend API обычный REST может быть значительно понятнее.
Если основными клиентами являются внешние партнеры и браузеры, привычный HTTP JSON API часто проще интегрировать и отлаживать.
Выбирать gRPC следует для решения конкретных задач межсервисного взаимодействия, а не как автоматическую замену REST.
Связанные термины
| Термин | Связь с gRPC |
|---|---|
| RPC | Базовая модель удаленного вызова процедур |
| Protocol Buffers | Основной формат описания и сериализации сообщений gRPC |
| API | gRPC является одним из способов построения программных интерфейсов |
| REST API | Распространенная альтернатива для HTTP-интеграций |
| Microservices | Один из основных сценариев использования gRPC |
| Kubernetes | Популярная среда запуска gRPC-сервисов |
| Service Mesh | Может управлять безопасностью и маршрутизацией gRPC-трафика |
| Istio | Может применять mTLS и политики к gRPC-соединениям |
| OpenTelemetry | Используется для распределенной трассировки RPC |
| CI/CD | Автоматизирует проверку контрактов и выпуск сервисов |
| Docker | Используется для контейнеризации gRPC Backend |
| Message Queue | Дополняет gRPC в асинхронных сценариях |
Краткий итог
gRPC — технология удаленного вызова процедур, предназначенная для быстрого и строго типизированного взаимодействия приложений и сервисов. Контракты обычно описываются через Protocol Buffers, после чего инструменты генерируют клиентский и серверный код.
gRPC поддерживает обычные Request-Response вызовы и несколько вариантов Streaming. Он особенно хорошо подходит для внутреннего взаимодействия микросервисов, сервисов на разных языках и систем с большим количеством частых сетевых вызовов.
При этом gRPC не отменяет основные проблемы распределенных систем. Необходимо настраивать Deadline, корректно использовать Retry, учитывать идемпотентность, совместимость контрактов, безопасность и Observability. Для публичных и простых API REST часто остается более удобным вариантом, поэтому выбор должен соответствовать архитектуре и клиентам системы.