← Назад к вопросам

Приведи пример взаимодействия компонентов в микросервисной архитектуре

1.3 Junior🔥 191 комментариев
#Клиент-серверная архитектура

Комментарии (1)

🐱
deepseek-v3.2PrepBro AI6 апр. 2026 г.(ред.)

Ответ сгенерирован нейросетью и может содержать ошибки

Пример взаимодействия компонентов в микросервисной архитектуре

В микросервисной архитектуре взаимодействие между компонентами (сервисами) является фундаментальным аспектом, так как каждый сервис выполняет определённую бизнес-функцию и должен общаться с другими для выполнения комплексных операций. Приведу пример из e-commerce системы (интернет-магазин), где заказ товара включает координацию нескольких сервисов. Этот пример иллюстрирует два основных паттерна взаимодействия: синхронный (HTTP/REST) и асинхронный (через брокер сообщений).

Архитектура примера

Рассмотрим упрощённую систему с четырьмя микросервисами:

  • Order Service (Сервис заказов): Управляет созданием и жизненным циклом заказов.
  • Inventory Service (Сервис инвентаря): Контролирует наличие товаров на складе.
  • Payment Service (Платежный сервис): Обрабатывает финансовые транзакции.
  • Notification Service (Сервис уведомлений): Отправляет email и push-уведомления пользователям.

Сценарий: Создание нового заказа

Пользователь через фронтенд (или API Gateway) инициирует создание заказа. Последовательность взаимодействий выглядит следующим образом:

1. Синхронный запрос к Inventory Service (HTTP/REST)

Order Service сначала должен убедиться, что товар есть в наличии. Он выполняет синхронный вызов к Inventory Service через REST API.

### Запрос от Order Service к Inventory Service
POST /api/inventory/check HTTP/1.1
Host: inventory-service:8080
Content-Type: application/json

{
  "productId": "12345",
  "quantity": 2
}

Inventory Service проверяет базу данных и отвечает:

{
  "inStock": true,
  "reserved": true
}

Если товара нет ("inStock": false), Order Service немедленно возвращает ошибку клиенту. Это пример синхронного, блокирующего взаимодействия.

2. Создание заказа и синхронный вызов Payment Service

После успешной проверки инвентаря Order Service создаёт запись о заказе в статусе PENDING в своей локальной БД и вызывает Payment Service для списания средств.

# Пример кода в Order Service (Python + requests)
import requests

def create_order(order_data):
    # ... проверка инвентаря ...

    # Сохраняем заказ локально
    order_id = save_order_to_db(order_data)

    # Синхронный вызов Payment Service
    payment_response = requests.post(
        'http://payment-service:8081/api/payments/charge',
        json={
            "orderId": order_id,
            "amount": order_data['total'],
            "cardToken": order_data['paymentToken']
        },
        timeout=10  # Таймаут для избежания вечного ожидания
    )

    if payment_response.status_code == 200:
        update_order_status(order_id, 'PAID')
        # Далее инициируем асинхронные события...
    else:
        update_order_status(order_id, 'FAILED')
        # И откатываем резервирование в Inventory Service (компенсирующая транзакция)

Это ещё один синхронный вызов. Система ждёт ответа от платёжного шлюза. Для повышения отказоустойчивости здесь часто применяют паттерн Circuit Breaker.

3. Асинхронное уведомление других сервисов через брокер сообщений (Kafka/RabbitMQ)

После успешной оплаты начинается асинхронная фаза. Order Service публикует событие в message broker (например, Apache Kafka), не дожидаясь реакции потребителей. Это ключевое отличие от синхронного стиля.

// Пример публикации события в Order Service (Java + Spring Kafka)
@Service
public class OrderEventPublisher {

    @Autowired
    private KafkaTemplate<String, Object> kafkaTemplate;

    public void publishOrderPaidEvent(Order order) {
        OrderPaidEvent event = new OrderPaidEvent(
            order.getId(),
            order.getCustomerEmail(),
            order.getTotalAmount()
        );

        // Публикация в топик "order-events"
        kafkaTemplate.send("order-eights", event);
        // Order Service не знает и не ждёт, кто и как обработает это событие.
    }
}

4. Асинхронная обработка события сервисами-потребителями

Два сервиса подписываются на топик order-events и обрабатывают событие OrderPaidEvent независимо и параллельно:

  • Inventory Service: Получает событие и окончательно уменьшает уровень товара на складе (списывает зарезервированное).
  • Notification Service: Получает то же самое событие и отправляет клиенту письмо с подтверждением заказа.
// Пример потребителя в Notification Service (Node.js + KafkaJS)
const consumer = kafka.consumer({ groupId: 'notification-group' })

await consumer.subscribe({ topic: 'order-events' })

await consumer.run({
    eachMessage: async ({ message }) => {
        const event = JSON.parse(message.value.toString())
        if (event.type === 'OrderPaidEvent') {
            // Отправка email асинхронно
            await sendConfirmationEmail(event.customerEmail, event.orderId)
        }
    }
})

Ключевые выводы и принципы

  • Комбинирование стилей: Реальные системы используют гибридный подход. Критичные для продолжения сценария шаги (проверка наличия, оплата) часто делают синхронными, а побочные эффекты (нотификации, обновления аналитики) — асинхронными через события.
  • Связность и независимость развёртывания: Каждый сервис имеет свою БД и может обновляться независимо. Inventory Service может изменить свою схему БД, не влияя на Order Service, пока контракт API или формата сообщений сохраняется.
  • Повышение отказоустойчивости: Асинхронная коммуникация через брокер повышает устойчивость. Если Notification Service временно недоступен, сообщения накапливаются в топике Kafka и будут обработаны после его восстановления.
  • Сложность координации: Недостатком является потеря простых ACID-d транзакций. Для обеспечения согласованности данных между сервисами приходится применять сложные паттерны, такие как Saga (как в нашем примере: если оплата fails, Order Service должен отправить событие для отмены резерва в Inventory Service).

Таким образом, взаимодействие в микросервисах — это проектирование сети слабосвязанных, специализированных компонентов, которые координируются через чёткие API-контракты и события, что обеспечивает масштабируемость и гибкость системы, но добавляет сложность в управлении транзакциями и мониторинге.

Приведи пример взаимодействия компонентов в микросервисной архитектуре | PrepBro