Как организовать коммуникацию между микросервисами
Микросервисы общаются двумя основными способами:
🟢 Junior Level
Микросервисы общаются двумя основными способами:
1. Синхронная (HTTP/gRPC):
Сервис A → HTTP запрос → Сервис B → HTTP ответ → Сервис A
2. Асинхронная (Kafka/RabbitMQ):
Сервис A → сообщение в Queue → Сервис B заберёт когда будет готов
🟡 Middle Level
Синхронная коммуникация
REST:
@RestController
public class OrderController {
private final UserServiceClient userService;
@GetMapping("/orders/{id}")
public Order getOrder(@PathVariable Long id) {
Order order = orderRepository.findById(id);
User user = userService.getUser(order.userId());
return new Order(order, user);
}
}
gRPC:
service UserService {
rpc GetUser (UserRequest) returns (UserResponse);
}
Асинхронная коммуникация
Kafka:
@KafkaListener(topics = "user-events")
public void onUserEvent(UserEvent event) {
if (event.type() == USER_CREATED) {
userRepository.save(event.toUser());
}
}
Типичные ошибки
- Cascading failures:
Service A → B → C → D D упал → C упал → B упал → A упал Решение: Circuit Breaker, Timeout
🔴 Senior Level
Архитектурные Trade-offs
Когда НЕ использовать синхронную коммуникацию
- Длинные цепочки вызовов (A→B→C→D) — cascade failure risk
- Фоновые задачи (отправка email, генерация отчёта)
- Высокая нагрузка — асинхронная лучше буферизует пики
| Синхронная | Асинхронная |
|---|---|
| Проще: один HTTP-вызов → ответ, нет overhead на broker и сериализацию. | Отказоустойчивее |
| Быстрее для простых случаев: нет overhead на broker и сериализацию. | Лучше для масштабирования |
| Coupling во времени | Decoupled |
| Cascading failures | Eventual consistency |
Production Experience
API Composition:
// thenCombine — объединяет два futures, дожидаясь обоих.
// join() — блокирует до результата (как get(), но без checked exception).
// Если один future упадёт — весь pipeline CompletableFuture завершится с ошибкой.
@GetMapping("/dashboard/{userId}")
public CompletableFuture<Dashboard> getDashboard(@PathVariable Long userId) {
CompletableFuture<User> user = userService.getUserAsync(userId);
CompletableFuture<List<Order>> orders = orderService.getOrdersAsync(userId);
CompletableFuture<List<Notification>> notifications =
notificationService.getNotificationsAsync(userId);
return user.thenCombine(orders, (u, o) ->
new Dashboard(u, o, notifications.join()));
}
Best Practices
✅ Асинхронная для событий
✅ Синхронная для запросов данных
✅ Circuit Breaker для синхронных вызовов
✅ Idempotency для асинхронных сообщений
❌ Длинные цепочки вызовов
❌ Без timeout и retry
❌ Без обработки ошибок
🎯 Шпаргалка для интервью
Обязательно знать:
- Два способа: синхронная (HTTP/gRPC) и асинхронная (Kafka/RabbitMQ)
- Синхронная: проще, мгновенный ответ, но cascade failure risk
- Асинхронная: отказоустойчивее, масштабируемость, но eventual consistency
- API composition: объединение результатов из нескольких сервисов (CompletableFuture.thenCombine)
- Circuit Breaker для синхронных вызовов обязателен
- Idempotency для асинхронных сообщений обязательна
- НЕ используйте синхронную для длинных цепочек (A→B→C→D), фоновых задач, высокой нагрузки
Частые уточняющие вопросы:
- REST vs gRPC? REST проще, gRPC быстрее (protobuf), строже контракт.
- Kafka vs RabbitMQ? Kafka — persistent log, replay, higher throughput. RabbitMQ — flexible routing, easier setup.
- Как избежать cascade failure? Circuit Breaker, Timeout, Retry — для синхронных; async queue — для фоновых.
- Что такое API composition? Запрос к нескольким сервисам параллельно, объединение результатов (thenCombine).
Красные флаги (НЕ говорить):
- “Синхронная всегда лучше, проще” — нет, cascade failure risk
- “Асинхронная для всего” — нет, сложнее дебажить, eventual consistency
- “Цепочка A→B→C→D→E — нормальная практика” — нет, cascade failure гарантирован
- “Idempotency не нужна для Kafka” — нужна, duplicate delivery возможен
Связанные темы:
- [[16. В чём разница между синхронной и асинхронной коммуникацией]]
- [[5. Что такое паттерн Circuit Breaker]]
- [[19. Что такое паттерн Retry и как его правильно использовать]]
- [[9. Что такое API Gateway и какие задачи он решает]]
- [[2. В чём разница между хореографией и оркестрацией в Saga]]