Как в микросервисной архитектуре организовано взаимодействие между сервисами?

«Как в микросервисной архитектуре организовано взаимодействие между сервисами?» — вопрос из категории Архитектура, который задают на 10% собеседований Java Разработчик. Ниже — развёрнутый ответ с разбором ключевых моментов.

Ответ

В микросервисной архитектуре взаимодействие между сервисами организуется через синхронные и асинхронные механизмы.

Синхронное взаимодействие (REST/gRPC):

  • Используется для прямых запросов, когда требуется немедленный ответ.
  • Пример с Spring Cloud OpenFeign:
    @FeignClient(name = "order-service", url = "${order.service.url}")
    public interface OrderServiceClient {
        @GetMapping("/orders/{id}")
        Order getOrder(@PathVariable Long id);
    }
  • Для надежности добавляются паттерны: Circuit Breaker (Resilience4j, Hystrix) для предотвращения каскадных сбоев и Retry для обработки временных ошибок.

Асинхронное взаимодействие (Message Brokers):

  • Используется для слабой связности и повышения отказоустойчивости.
  • Пример с Apache Kafka и Spring Kafka:

    @Service
    public class OrderEventProducer {
        @Autowired
        private KafkaTemplate<String, OrderEvent> kafkaTemplate;
    
        public void publishOrderCreated(OrderEvent event) {
            kafkaTemplate.send("order-created-topic", event);
        }
    }
  • Преимущества: буферизация, возможность повторной обработки, независимость сервисов.

Практические рекомендации:

  1. Для командных запросов используйте API Gateway.
  2. Всегда реализуйте механизмы идемпотентности для повторяющихся операций.
  3. Используйте формат сообщений (например, Avro, Protobuf) для контрактов между сервисами.