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

Что такое принципы микросервисного подхода?

2.0 Middle🔥 191 комментариев
#DevOps и инфраструктура#Django

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

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

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

Принципы микросервисного подхода

Микросервисный подход (Microservices Architecture) — это стиль архитектуры приложения, в котором система разбивается на малые, независимые сервисы, каждый из которых работает в отдельном процессе и взаимодействует с другими через четко определённые интерфейсы.

Основные принципы микросервисного подхода

1. Разделение по бизнес-функциям (Domain-Driven Design)

Каждый сервис отвечает за одну бизнес-функцию или bounded context:

# Плохо — разделение по слоям
users_service/
  users/
  orders/
  payments/

# Хорошо — разделение по бизнес-функциям
user_service/
  domain/
  application/
  infrastructure/

order_service/
  domain/
  application/
  infrastructure/

payment_service/
  domain/
  application/
  infrastructure/

2. Независимость и автономность

Каждый сервис может быть:

  • Разработан отдельной командой
  • Развёрнут независимо
  • Масштабирован отдельно
  • Написан на разных языках
# User Service на Python
user_service/
  main.py
  requirements.txt

# Order Service на Node.js
order_service/
  index.js
  package.json

# Payment Service на Go
payment_service/
  main.go
  go.mod

3. Собственная база данных

Каждый сервис имеет свою БД, нет общей БД (Database per Service):

user_service:
  - PostgreSQL для хранения пользователей
  - Не может писать в БД других сервисов

order_service:
  - MongoDB для хранения заказов
  - Не может писать в БД других сервисов

payment_service:
  - PostgreSQL для хранения платежей
  - Не может писать в БД других сервисов

# Синхронизация через API или Event Bus

4. Взаимодействие через API

Сервисы общаются через REST, gRPC, или асинхронные очереди:

# User Service
from fastapi import FastAPI

app = FastAPI()

@app.get("/api/v1/users/{user_id}")
async def get_user(user_id: int):
    return {"id": user_id, "name": "John"}

# Order Service вызывает User Service
import httpx

async def create_order(user_id: int, items: list):
    async with httpx.AsyncClient() as client:
        user = await client.get(f"http://user-service/api/v1/users/{user_id}")
    
    if not user.ok:
        raise ValueError("User not found")
    
    # Создание заказа
    return {"order_id": 123, "user_id": user_id, "items": items}

5. Асинхронное взаимодействие через Event Bus

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

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

def create_order(order_data):
    # Сохранение заказа в БД
    order = save_to_db(order_data)
    
    # Публикация события
    producer.send("order.created", {
        "order_id": order.id,
        "user_id": order.user_id,
        "total": order.total
    })
    
    return order

# Payment Service слушает событие
from kafka import KafkaConsumer

consumer = KafkaConsumer(
    "order.created",
    bootstrap_servers=["kafka:9092"],
    value_deserializer=lambda m: json.loads(m.decode())
)

for message in consumer:
    order_data = message.value
    # Инициирование платежа
    process_payment(order_data["total"])

6. Независимый цикл развёртывания

# Развёртывание одного сервиса не влияет на другие

# Развернуть новую версию User Service
docker build -t user-service:v2.1 .
docker push user-service:v2.1
kubectl set image deployment/user-service user-service=user-service:v2.1

# Order Service и Payment Service продолжают работать без перезагрузки

7. Отказоустойчивость и резилентность

import httpx
from tenacity import retry, wait_exponential, stop_after_attempt

@retry(
    wait=wait_exponential(multiplier=1, min=2, max=10),
    stop=stop_after_attempt(3)
)
async def call_user_service(user_id: int):
    """Повтор при ошибке с экспоненциальной задержкой"""
    async with httpx.AsyncClient(timeout=5.0) as client:
        response = await client.get(f"http://user-service/api/v1/users/{user_id}")
        response.raise_for_status()
        return response.json()

# Circuit Breaker паттерн
from pybreaker import CircuitBreaker

breaker = CircuitBreaker(fail_max=5, reset_timeout=60)

@breaker
async def call_payment_service():
    # Если много ошибок, разорвёт цепь и вернёт ошибку быстро
    pass

8. Масштабирование отдельно

# Если User Service перегружен — масштабируем только его
kubectl scale deployment user-service --replicas=5

# Order Service и Payment Service остаются на 2 реплика
kubectl scale deployment order-service --replicas=2
kubectl scale deployment payment-service --replicas=2

Преимущества микросервисов

  • Гибкость: каждый сервис может быть переписан отдельно
  • Масштабируемость: масштабируем только перегруженные сервисы
  • Надёжность: отказ одного сервиса не валит все
  • Скорость разработки: команды работают параллельно
  • Независимость: разные технологии для разных задач
  • Лёгкое развёртывание: быстрые релизы

Недостатки микросервисов

  • Сложность: распределённая система сложнее
  • Сетевые задержки: вызовы через сеть медленнее
  • Консистентность данных: сложнее обеспечить ACID
  • Мониторинг: нужны сложные инструменты логирования
  • Тестирование: интеграционные тесты сложнее
  • Операции: нужно больше инфраструктуры (Docker, Kubernetes)

Примеры использования

Синхронная коммуникация

# Клиент → Order Service → User Service
@app.post("/api/v1/orders")
async def create_order(order: OrderSchema, user_id: int):
    # Проверяем пользователя в User Service
    user = await get_user(user_id)
    
    if not user:
        raise HTTPException(status_code=404)
    
    # Сохраняем заказ
    db_order = Order(
        user_id=user_id,
        items=order.items,
        total=order.total
    )
    db.add(db_order)
    db.commit()
    
    return db_order

Асинхронная коммуникация

# Saga паттерн для транзакций
class OrderSaga:
    def __init__(self, event_bus):
        self.event_bus = event_bus
    
    async def create_order_with_payment(self, order_data):
        # Шаг 1: создаём заказ
        order = await self.create_order(order_data)
        
        try:
            # Шаг 2: публикуем событие создания заказа
            await self.event_bus.publish("order.created", order)
            
            # Шаг 3: ждём события платежа
            payment_result = await self.wait_for_payment(order.id)
            
            if payment_result.success:
                # Шаг 4: подтверждаем заказ
                await self.confirm_order(order.id)
                return order
            else:
                # Откат: отменяем заказ
                await self.cancel_order(order.id)
                raise Exception("Payment failed")
        
        except Exception as e:
            # Откатываем все изменения
            await self.cancel_order(order.id)
            raise

Паттерны микросервисов

  • API Gateway: единая точка входа
  • Service Discovery: поиск сервисов по имени
  • Circuit Breaker: защита от каскадных отказов
  • Event Sourcing: история всех событий
  • Saga: управление распределёнными транзакциями
  • CQRS: разделение чтения и записи

Микросервисный подход — это не серебряная пуля, а выбор архитектуры, который имеет смысл для больших, сложных систем.