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

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

2.4 Senior🔥 81 комментариев
#API и сетевые протоколы#Архитектура и паттерны

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

🐱
claude-haiku-4.5PrepBro AI29 мар. 2026 г.(ред.)

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

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

Взаимодействие микросервисов — критическая часть распределенной архитектуры. Я использую несколько подходов в зависимости от требований проекта: синхронные вызовы (REST/gRPC), асинхронные сообщения (очереди), и события.

1. REST API между сервисами

Простой и распространенный подход для синхронного взаимодействия:

// orders-service/src/services/OrderService.ts
import axios from 'axios';

export class OrderService {
  private paymentServiceUrl = process.env.PAYMENT_SERVICE_URL;
  private inventoryServiceUrl = process.env.INVENTORY_SERVICE_URL;

  async createOrder(userId: string, items: Item[]) {
    // 1. Проверяем наличие товара в inventory-service
    const inventoryCheck = await axios.post(
      `${this.inventoryServiceUrl}/api/v1/inventory/reserve`,
      { items }
    );

    if (!inventoryCheck.data.success) {
      throw new Error('Items not available');
    }

    // 2. Обрабатываем платеж через payment-service
    const payment = await axios.post(
      `${this.paymentServiceUrl}/api/v1/payments`,
      { userId, amount: items.reduce((s, i) => s + i.price, 0) }
    );

    // 3. Сохраняем заказ
    return await this.orderRepository.create({
      userId,
      items,
      paymentId: payment.data.id
    });
  }
}

Проблемы с простым REST: нет retry-логики при отказе, нет timeout-ов, нет circuit breaker-а, нет мониторинга.

2. Resilience4j / Circuit Breaker

Добавляю circuit breaker для надежности:

// shared/infrastructure/CircuitBreakerService.ts
import { CircuitBreaker } from 'opossum';

export class ResilientHttpService {
  private breaker: CircuitBreaker;
  private client = axios.create();

  constructor(serviceName: string) {
    const options = {
      timeout: 3000,           // timeout 3 секунды
      errorThresholdPercentage: 50, // 50% ошибок = открыть breaker
      resetTimeout: 30000,     // 30 сек до попытки полугзакрытого состояния
      name: serviceName,
      // Fallback при отказе
      fallback: () => ({ error: 'Service unavailable, using cache' })
    };

    this.breaker = new CircuitBreaker(
      (url: string, data?: any) => this.client.post(url, data),
      options
    );
  }

  async request(url: string, data?: any) {
    return this.breaker.fire(url, data);
  }
}

Использование:

export class OrderService {
  private paymentHttp = new ResilientHttpService('payment-service');

  async createOrder(order: CreateOrderDto) {
    try {
      const payment = await this.paymentHttp.request(
        `${process.env.PAYMENT_SERVICE_URL}/api/v1/payments`,
        order
      );
      return payment;
    } catch (error) {
      // Fallback: сохранить в очередь для отложенной обработки
      await this.postponedOrderQueue.add(order);
    }
  }
}

3. Асинхронная коммуникация с очередями

Для асинхронных операций использую RabbitMQ или Redis. Публикую события, которые обрабатывают другие сервисы асинхронно. Это развязывает зависимости между сервисами и позволяет справиться с пиками нагрузки.

Преимущества асинхронного подхода:

  • Сервис А не ждет, пока сервис Б обработает событие
  • Если сервис Б упал, событие можно переобработать позже
  • Легко добавить новых подписчиков без изменения отправителя
  • Масштабируется лучше чем синхронные вызовы

4. gRPC для высокопроизводительного взаимодействия

Для критичных сервисов использую gRPC вместо REST:

  • Быстрее (протокол на основе Protocol Buffers)
  • Типизированный контракт
  • Поддерживает streaming
  • Меньше overhead чем HTTP/JSON

5. Service Mesh (Istio/Linkerd)

Для очень сложных систем использую Service Mesh для управления трафиком между сервисами:

  • Retry-логика на уровне mesh
  • Load balancing
  • Circuit breaking
  • Observability (трейсинг, метрики)

6. Мониторинг и Tracing

Использую OpenTelemetry и Jaeger для отладки распределенных систем. Каждый вызов между сервисами логируется и трейсируется, что помогает выявлять узкие места и баги в асинхронных системах.

Как выбираю подход

СценарийПодходПочему
Синхронный с гарантиейREST + Circuit BreakerПростой, надежный
Асинхронный workflowRabbitMQ + eventМасштабируемо, развязано
Высокая нагрузкаgRPCБыстрый, типизированный
Критичная системаService Mesh + ObservabilityКонтроль, мониторинг

Итог

Не существует "серебряной пули". Выбираю технологию в зависимости от требований: нужна синхронность — REST + Circuit Breaker, нужна масштабируемость — очереди, нужна производительность — gRPC, нужна надежность — Service Mesh.

Главный принцип: начинаю с простого (REST), добавляю сложность только когда она нужна. Новичков часто пугает сложность микросервисов, но реально 80% систем работают на базовом REST с circuit breaker-ом и асинхронными очередями для тяжелых операций.