Синхронная коммуникация
Основы: Типы взаимодействия между системами, API и HTTP.
Синхронная коммуникация
Что такое синхронная коммуникация?
Клиент нажимает "Оплатить" и ждёт на экране спиннер, пока сервер не вернёт успех или ошибку — это синхронная модель. Синхронная коммуникация — способ взаимодействия, при котором отправитель отправляет запрос и ждёт ответа от получателя в том же логическом шаге.
Подход широко используется в микросервисной архитектуре для операций с немедленным результатом — проверка остатка, расчёт скидки, получение профиля. Для фона (письма, отчёты) берут асинхронную коммуникацию.
Синхронная коммуникация предполагает блокирующее взаимодействие: инициатор запроса ожидает завершения операции и получения ответа до продолжения выполнения. Клиент и сервер связаны во времени — задержка ответа напрямую влияет на производительность вызывающей стороны.
Примерами синхронности являются HTTP и RPC:
- HTTP/HTTPS - клиент отправляет HTTP-запрос (например, GET или POST), и сервер немедленно отвечает на этот запрос.
- RPC (Remote Procedure Call) - вызов удалённой процедуры, где клиент ожидает результата выполнения функции на сервере.
Для HTTP(S) используется, как правило, REST, а для RPC - gRPC.
Play ITЗагрузка интерактивного демо…
HTTP

HTTP — протокол прикладного уровня, реализующий модель запрос-ответ поверх надёжного транспорта (обычно TCP). HTTPS добавляет шифрование через TLS/SSL.
Архитектурные особенности
- Состояние не сохраняется между запросами (stateless): каждый запрос должен содержать всю необходимую контекстную информацию.
- Версии протокола:
- HTTP/1.1: поддержка постоянных соединений (keep-alive), конвейеризация (pipeline) ограничена.
- HTTP/2 — мультиплексирование потоков поверх одного TCP-соединения, сжатие заголовков (HPACK), серверные отправки (server push).
- HTTP/3: замена транспорта с TCP на QUIC (поверх UDP) для снижения задержки при установке соединения и устойчивости к потере пакетов.
- Методы запросов определяют семантику операции — GET (получение), POST (создание/действие), PUT/PATCH (обновление), DELETE (удаление).
- Коды состояния группируются по классам — 2xx (успех), 3xx (перенаправление), 4xx (ошибка клиента), 5xx (ошибка сервера).
Механизмы надёжности
- Повтор запроса при сетевых сбоях осуществляется на уровне приложения (идемпотентные методы GET, PUT, DELETE допускают безопасный повтор).
- Таймауты соединения и чтения настраиваются на клиенте и сервере.
- Для критичных операций применяется идемпотентность через идентификаторы запросов (например, идемпотентные ключи в платежных системах).
Ограничения синхронной модели
- Блокировка потока выполнения до получения ответа.
- Ограниченное время ожидания (таймауты прокси, балансировщиков, клиентских библиотек).
- Неэффективность для длительных операций (долгие вычисления, внешние интеграции) — требуется применение паттернов опроса (polling) или асинхронных обратных вызовов.
Типичные сценарии применения
- Веб-интерфейсы и мобильные клиенты.
- Интеграция между сервисами с низкой задержкой и простой семантикой запроса.
- RESTful API с чёткими контрактами и идемпотентными операциями.
RPC

RPC (Remote Procedure Call) — абстракция, позволяющая вызывать функцию на удалённом узле так, будто она локальная. Синхронная реализация подразумевает блокирующее ожидание результата.
Архитектурные особенности
- Стек вызова расширяется через сеть: клиент сериализует параметры → отправляет запрос → ожидает ответ → десериализует результат/исключение.
- Типы реализаций:
- gRPC (Google) — бинарный протокол поверх HTTP/2, IDL на основе Protocol Buffers, поддержка потоковой передачи.
- Apache Thrift — мультиязыковая поддержка, собственный бинарный протокол (также поддерживает HTTP, JSON).
- JSON-RPC / XML-RPC: текстовые форматы поверх HTTP, простота отладки ценой производительности.
- CORBA (устаревший): сложная распределённая объектная модель с поддержкой транзакций и безопасности.
- Контракт интерфейса строго определяется в IDL (Interface Definition Language), что обеспечивает типобезопасность на этапе компиляции.
Механизмы надёжности
- Автоматические повторы (retry) с экспоненциальной задержкой и ограничением количества попыток.
- Таймауты на уровне вызова (deadline propagation) — критично для предотвращения каскадных отказов.
- Трассировка распределённых вызовов через контекстные заголовки (например, trace ID в gRPC metadata).
- Обнаружение сервисов (service discovery) и балансировка нагрузки на уровне клиента (client-side load balancing).
Проблемы синхронного RPC
- Сетевые разделения приводят к блокировке или таймаутам вызывающего потока.
- Каскадные отказы: медленный зависимый сервис блокирует все вызывающие его компоненты.
- Сложность обеспечения согласованности при распределённых транзакциях.
- Отсутствие встроенной очереди: пиковая нагрузка может привести к отказу сервиса.
Типичные сценарии применения
- Высокопроизводительные внутренние API между микросервисами с низкой задержкой.
- Системы, требующие строгой типизации и автоматической генерации клиентских библиотек.
- Синхронные операции с предсказуемым временем выполнения (менее 100–500 мс).
HTTP(S) работают по модели "запрос-ответ", поэтому всегда подразумевает клиент-серверное взаимодействие, ведь клиент (веб-браузер или приложение) формирует и отправляет запрос на сервер, а сервер, получает запрос, обрабатывает его и отправляет ответ клиенту.
Детали HTTP, заголовков и кэша — в HTTP как основа веб-интеграций и REST. Ниже — RPC-стек и GraphQL для внутренних и гибких API.
gRPC, GraphQL
Учебное сравнение трёх стилей на сценарии "пользователь + заказы" (цепочка REST, один GraphQL-query, unary gRPC) — в основах REST, GraphQL и gRPC — стили API. Ниже — сводка для микросервисной архитектуры.
| Критерий | REST + JSON | gRPC + Protobuf | GraphQL |
|---|---|---|---|
| Контракт | OpenAPI, соглашения | .proto, кодогенерация | Schema, introspection |
| Транспорт | HTTP/1.1–2 | HTTP/2 | Обычно HTTP POST |
| Клиент | Браузер, мобильные | Сервис-сервис | Часто BFF / мобильные |
| Гибкость полей | Over/under-fetching | Фиксированные сообщения | Клиент выбирает поля |
| Типичное место | Публичный API | Внутренние вызовы | Агрегация для UI |
gRPC (Google Remote Procedure Call) — фреймворк для высокопроизводительных RPC-сервисов. В отличие от REST, gRPC использует HTTP/2 и Protocol Buffers (Protobuf).
Полная документация доступна здесь - https://grpc.io/
Этот подход лучше использовать для высокопроизводительных систем с большим объёмом данных, и если требуется строгая типизация и автоматическая генерация кода.
Protocol Buffers (Protobuf) — это специальный формат для описания контрактов (схем данных) и сериализации. Protobuf более компактный и быстрый, чем JSON.
HTTP/2 используется для передачи данных, что обеспечивает высокую производительность благодаря мультиплексированию, сжатию заголовков и двунаправленным потокам.
GraphQL — это язык запросов и среда выполнения для API, разработанный Facebook в 2012 году. Он позволяет клиентам запрашивать только те данные, которые им нужны, что делает его более гибким по сравнению с традиционными REST API. Клиент может указать точную структуру данных, которые он хочет получить.
Документация здесь - https://graphql.org/
Чит-лист - https://cheatsheets.zip/graphql
В отличие от REST, где каждый ресурс имеет свой URL, GraphQL использует один эндпоинт для всех запросов. GraphQL использует схему, которая определяет доступные данные и их типы, предоставляя документацию.
Сценарий в MSA — User Service и Order Service
Типичная схема из продакшена: внешний клиент (веб, мобильное приложение) и два доменных сервиса. Как меняется граница ответственности клиента — зависит от стиля API на границе.
| Стиль на границе | Кто ходит в Order Service | Риск для клиента |
|---|---|---|
| REST | Сам клиент (второй GET /orders/{id}) | N+1 запросов, хрупкость при смене URL заказов |
| GraphQL | BFF / GraphQL-слой по схеме | Сложность шлюза, лимиты глубины query |
| gRPC | Обычно другой сервис (оркестратор, BFF), не браузер | Жёсткий контракт .proto, нужна кодогенерация |
REST. API Gateway или клиент вызывает User Service, затем Order Service. Между сервисами при этом тоже может быть gRPC — REST остаётся контрактом "наружу".
GraphQL. Один POST /graphql на BFF; резолверы внутри параллельно дергают User и Order (DataLoader, batching). Клиент не знает про разбиение на микросервисы.
gRPC. orders-api вызывает catalog-api через GetProduct / ReserveStock с deadline в metadata; мобильному клиенту отдают REST или GraphQL с того же BFF. Unary и streaming-режимы — в основах.
Сквозной REST между двумя сервисами (каталог и заказы) — 8.08 Практикум REST и WebSocket. Там же JWT, API-ключ между сервисами и WebSocket для UI.
Паттерны устойчивости для sync-вызовов
Синхронная цепочка быстро деградирует, если один сервис в середине стал медленным. В продакшене поверх HTTP/gRPC обычно включают такие паттерны:
- Timeout budget — общий лимит на всю цепочку (например, 800 мс), а не только на один hop.
- Retry с backoff и jitter — только для идемпотентных операций (
GET,PUT, безопасныеPOSTс idempotency-key). - Circuit breaker — временно "размыкает" вызов к деградировавшему downstream, чтобы не положить весь сервис.
- Bulkhead — отдельные пулы соединений/потоков для разных интеграций.
- Fallback — отдача кэша/частичного ответа, если зависимый сервис недоступен.
Минимальный практический чек-лист для команды:
- На каждом клиенте явно задать
connect timeoutиread/deadline timeout. - Добавить
x-request-id/trace-idв каждый запрос. - Логировать код ответа, latency, retry-count.
- Завести алерт по p95/p99 и доле
5xxдля критичных endpoint.
Эти паттерны дополняют балансировку нагрузки и асинхронную коммуникацию, а не заменяют их.
Пример реализации
gRPC с Protocol Buffers
Определение контракта (.proto файл)
Код ITЗагрузка примера кода…
Разбор:
syntaxиpackageзадают версию proto и пространство имён;serviceобъявляет RPC-методы;message— структуры полей на проводе.
Реализация на C#
Сервер:
Код ITЗагрузка примера кода…
Разбор:
AddHostedService<NotificationConsumer>()регистрирует слушателя очереди в DI;MapControllers()подключает REST-эндпоинты.- Пространства имён группируют модели и сервисы;
async/awaitне блокируют поток при HTTP-вызове наружу.
Клиент:
Код ITЗагрузка примера кода…
Разбор:
- Пространства имён группируют модели и сервисы;
async/awaitне блокируют поток при HTTP-вызове наружу.
Реализация на Python
Сервер:
Код ITЗагрузка примера кода…
Разбор:
- Импорты подключают модули проекта; выполнение идёт сверху вниз — сначала конфигурация, затем объявление сущностей или маршрутов.
Клиент:
Код ITЗагрузка примера кода…
Разбор:
- Импорты подключают модули проекта; выполнение идёт сверху вниз — сначала конфигурация, затем объявление сущностей или маршрутов.
Реализация на Java
Сервер:
Код ITЗагрузка примера кода…
Разбор:
- Пакеты
model,repository,serviceразделяют слои — сущность, доступ к данным, бизнес-логика обработки заказов.
Клиент:
Код ITЗагрузка примера кода…
Разбор:
- Пакеты
model,repository,serviceразделяют слои — сущность, доступ к данным, бизнес-логика обработки заказов.
GraphQL
Схема типов (schema.graphql)
Код ITЗагрузка примера кода…
Разбор:
- Схема GraphQL описывает типы, запросы и подписки; директивы
@key,@externalиспользуются в federation подграфов.
Реализация на C# (Hot Chocolate)
Модели:
Код ITЗагрузка примера кода…
Разбор:
- Пространства имён группируют модели и сервисы;
async/awaitне блокируют поток при HTTP-вызове наружу.
Резолверы:
Код ITЗагрузка примера кода…
Разбор:
- Пространства имён группируют модели и сервисы;
async/awaitне блокируют поток при HTTP-вызове наружу.
Настройка сервера:
var builder = WebApplication.CreateBuilder(args);
builder.Services
.AddGraphQLServer()
.AddQueryType<Query>()
.AddMutationType<Mutation>()
.AddSubscriptionType<Subscription>()
.AddType<UserType>()
.AddType<PostType>();
var app = builder.Build();
app.MapGraphQL();
app.Run();
Разбор:
AddHostedService<NotificationConsumer>()регистрирует слушателя очереди в DI;MapControllers()подключает REST-эндпоинты.- Пространства имён группируют модели и сервисы;
async/awaitне блокируют поток при HTTP-вызове наружу.
Типы GraphQL:
Код ITЗагрузка примера кода…
Разбор:
- Пространства имён группируют модели и сервисы;
async/awaitне блокируют поток при HTTP-вызове наружу.
Реализация на Python (Strawberry)
Схема и резолверы:
Код ITЗагрузка примера кода…
Разбор:
- Импорты подключают модули проекта; выполнение идёт сверху вниз — сначала конфигурация, затем объявление сущностей или маршрутов.
Запуск сервера (FastAPI):
from fastapi import FastAPI
from strawberry.fastapi import GraphQLRouter
graphql_app = GraphQLRouter(schema)
app = FastAPI()
app.include_router(graphql_app, prefix="/graphql")
if __name__ == "__main__":
import uvicorn
uvicorn.run(app, host="0.0.0.0", port=8000)
Разбор:
FastAPI()создаёт приложение; декораторы@app.post/@app.getрегистрируют маршруты и схемы ответаresponse_model.Depends(get_db)внедряет сессию БД;BackgroundTasksоткладывает публикацию в RabbitMQ, чтобы HTTP-ответ ушёл клиенту быстрее.pika.BlockingConnectionиbasic_publishотправляют JSON-событие в очередьorder_events;delivery_mode=2помечает сообщение persistent.- Перед вставкой проверяется уникальность
order_number;HTTPException(400)и(404)возвращают понятные коды клиенту.
Реализация на Java (GraphQL Java)
Схема:
Код ITЗагрузка примера кода…
Разбор:
- Пакеты
model,repository,serviceразделяют слои — сущность, доступ к данным, бизнес-логика обработки заказов.
DataFetcher для запросов:
Код ITЗагрузка примера кода…
Разбор:
- Пакеты
model,repository,serviceразделяют слои — сущность, доступ к данным, бизнес-логика обработки заказов.
Модели:
Код ITЗагрузка примера кода…
Разбор:
- Пакеты
model,repository,serviceразделяют слои — сущность, доступ к данным, бизнес-логика обработки заказов.
Запуск сервера (Spring Boot):
Код ITЗагрузка примера кода…
Разбор:
- Пакеты
model,repository,serviceразделяют слои — сущность, доступ к данным, бизнес-логика обработки заказов.
Примеры запросов и мутаций
Запрос пользователя с постами:
query {
user(id: "1") {
id
name
email
isActive
posts {
id
title
publishedAt
}
}
}
Разбор:
- Схема GraphQL описывает типы, запросы и подписки; директивы
@key,@externalиспользуются в federation подграфов.
Список пользователей с пагинацией:
query {
users(page: 1, pageSize: 5) {
id
name
email
posts {
id
title
}
}
}
Разбор:
- Схема GraphQL описывает типы, запросы и подписки; директивы
@key,@externalиспользуются в federation подграфов.
Создание пользователя:
mutation {
createUser(name: "Тимур", email: "timur@example.com", isActive: true) {
id
name
email
createdAt
}
}
Разбор:
- Схема GraphQL описывает типы, запросы и подписки; директивы
@key,@externalиспользуются в federation подграфов.
Создание поста:
Код ITЗагрузка примера кода…
Разбор:
- Схема GraphQL описывает типы, запросы и подписки; директивы
@key,@externalиспользуются в federation подграфов.
Фрагменты для повторного использования:
Код ITЗагрузка примера кода…
Разбор:
- Схема GraphQL описывает типы, запросы и подписки; директивы
@key,@externalиспользуются в federation подграфов.
Параметризованный запрос:
Код ITЗагрузка примера кода…
Разбор:
- Схема GraphQL описывает типы, запросы и подписки; директивы
@key,@externalиспользуются в federation подграфов.
См. также
- Базовая глава в разделе "Система и сеть" — Типы взаимодействия между системами
- Коммуникация и интеграция
- Справочник по gRPC
- Go для микросервисов — типичный стек для gRPC-сервисов
Базовый разбор HTTP и HTTPS находится в отдельной статье — HTTP как основа веб-интеграций.