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

Какие знаешь способы микросервисного общения?

2.3 Middle🔥 171 комментариев
#REST API и HTTP#Архитектура и паттерны#Брокеры сообщений

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

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

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

Какие знаешь способы микросервисного общения

Микросервисы взаимодействуют между собой разными способами в зависимости от требований к синхронности, задержкам и надёжности. Вот основные подходы:

1. Синхронное общение: REST API / HTTP

Самый распространённый способ — прямые HTTP запросы между сервисами.

# Order Service вызывает Payment Service
import requests

def process_order(order_id):
    order = get_order(order_id)
    
    # Синхронный запрос к Payment Service
    response = requests.post(
        'http://payment-service:8000/api/payments',
        json={
            'order_id': order_id,
            'amount': order.total
        }
    )
    
    if response.status_code == 200:
        return 'Order processed'
    else:
        raise Exception('Payment failed')

Плюсы:

  • Просто и понятно
  • Не нужна доп. инфраструктура

Минусы:

  • Если Payment Service упал, падает Order Service
  • Медленно (HTTP overhead)
  • Тугие связи между сервисами

2. REST с асинхронными колбэками

Сервис отправляет запрос и указывает callback URL для получения результата.

# Order Service
def process_order(order_id):
    order = get_order(order_id)
    
    # Запрашиваем платёж с callback'ом
    requests.post(
        'http://payment-service:8000/api/payments',
        json={
            'order_id': order_id,
            'amount': order.total,
            'callback_url': 'http://order-service:8000/webhooks/payment-complete'
        }
    )
    
    return 'Payment processing...'

# Вебхук - Payment Service вызвает это
@app.post('/webhooks/payment-complete')
def payment_complete(payment_id, status):
    order = Order.get(payment_id=payment_id)
    order.status = 'completed' if status == 'success' else 'failed'
    order.save()

Плюсы:

  • Асинхронно, не блокирует
  • Простая реализация

Минусы:

  • Callback может не дойти
  • Нужно хранить callback URLs
  • Сложнее дебажить

3. Message Broker: Kafka / RabbitMQ

Сервисы не общаются напрямую, а публикуют события в брокер сообщений.

# Order Service - публикует событие
import kafka

producer = kafka.KafkaProducer(
    bootstrap_servers=['localhost:9092'],
    value_serializer=lambda v: json.dumps(v).encode()
)

def create_order(order_data):
    order = Order.create(order_data)
    
    # Публикуем событие
    producer.send('order.created', {
        'order_id': order.id,
        'amount': order.total,
        'customer_id': order.customer_id
    })
    
    return order

# Payment Service - подписывается на события
consumer = kafka.KafkaConsumer(
    'order.created',
    bootstrap_servers=['localhost:9092'],
    group_id='payment-service',
    value_deserializer=lambda m: json.loads(m.decode())
)

for message in consumer:
    event = message.value
    process_payment(event['order_id'], event['amount'])
    
    # Публикуем своё событие
    producer.send('payment.completed', {
        'order_id': event['order_id'],
        'status': 'success'
    })

# Inventory Service - тоже подписывается на order.created
# и резервирует товары

Плюсы:

  • Слабые связи между сервисами
  • Масштабируемость (multiple consumers)
  • История событий
  • Асинхронно и надёжно

Минусы:

  • Сложнее в настройке
  • Консистентность (eventual consistency)
  • Нужно обрабатывать duplicates

4. RPC (Remote Procedure Call): gRPC

Вызов функции удалённого сервиса как локальной.

# payment_service.proto
service PaymentService {
  rpc ProcessPayment(PaymentRequest) returns (PaymentResponse);
}

message PaymentRequest {
  string order_id = 1;
  float amount = 2;
}

message PaymentResponse {
  string transaction_id = 1;
  bool success = 2;
}

# order_service.py
import grpc
from payment_pb2 import PaymentRequest
from payment_pb2_grpc import PaymentServiceStub

def process_order(order_id):
    # Подключаемся к Payment Service
    channel = grpc.aio.secure_channel(
        'payment-service:50051',
        grpc.ssl_channel_credentials()
    )
    stub = PaymentServiceStub(channel)
    
    # Вызываем RPC метод
    response = stub.ProcessPayment(
        PaymentRequest(order_id=order_id, amount=99.99)
    )
    
    return response.success

Плюсы:

  • Быстрее REST (бинарный протокол)
  • Типизированный
  • Поддержка streaming

Минусы:

  • Синхронно (нужны async обёртки)
  • Тугие связи
  • Сложнее дебажить

5. NATS Messaging

Легковесный message broker для микросервисов.

from nats.aio.client import Client
import json

nc = Client()
await nc.connect('nats://localhost:4222')

# Публикация сообщения
await nc.publish('orders.created', json.dumps({
    'order_id': 123,
    'amount': 99.99
}).encode())

# Подписка на сообщения
async def message_handler(msg):
    data = json.loads(msg.data.decode())
    process_order(data['order_id'])

await nc.subscribe('orders.created', cb=message_handler)

6. GraphQL Federation

Несколько микросервисов с собственными GraphQL схемами, объединённые в одну.

# order_service/schema.graphql
type Query {
  order(id: ID!): Order
}

type Order {
  id: ID!
  amount: Float!
  payment: Payment  # От payment service
}

# payment_service/schema.graphql
type Query {
  payment(id: ID!): Payment
}

type Payment {
  id: ID!
  status: String!
}

# Apollo Federation объединяет эти схемы
# Клиент видит один unified GraphQL API

7. Service Mesh (Istio, Linkerd)

Отдельный слой для коммуникации микросервисов.

# Istio VirtualService
apiVersion: networking.istio.io/v1beta1
kind: VirtualService
metadata:
  name: order-service
spec:
  hosts:
  - order-service
  http:
  - match:
    - uri:
        prefix: /api/orders
    route:
    - destination:
        host: order-service
        port:
          number: 8000
        weight: 90
    - destination:
        host: order-service-v2
        port:
          number: 8000
        weight: 10  # Canary deployment

Сравнение способов

СпособСинхронностьСкоростьНадёжностьСложностьCoupling
REST HTTPСинхронноМедленноНизкаяНизкаяВысокий
gRPCСинхронноБыстроНизкаяСредняяВысокий
KafkaАсинхронноБыстроВысокаяВысокаяНизкий
RabbitMQАсинхронноСреднеВысокаяСредняяНизкий
NATSАсинхронноБыстроСредняяСредняяНизкий
GraphQL FederationСинхронноМедленноСредняяВысокаяСредний

Рекомендации

Используй REST когда:

  • Простые микросервисы
  • Низкая нагрузка
  • Нужны синхронные ответы

Используй Kafka когда:

  • Высокая нагрузка
  • Нужна история событий
  • Множество потребителей события
  • Сложные бизнес-процессы

Используй gRPC когда:

  • Нужна максимальная производительность
  • Строгие SLA
  • Стабильные API

Используй Service Mesh когда:

  • Десятки/сотни микросервисов
  • Kubernetes окружение
  • Нужны advanced routing, retry, circuit breaker

В заключение: выбор способа коммуникации зависит от требований. Часто в одной системе используются несколько подходов: REST для sync операций, Kafka для events, gRPC для performance critical части.

Какие знаешь способы микросервисного общения? | PrepBro