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

Какие знаешь паттерны для проектирования распределенных систем?

2.4 Senior🔥 132 комментариев
#Архитектура систем#Требования и их анализ

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

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

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

Какие знаешь паттерны для проектирования распределённых систем

Распределённые системы требуют специальных паттернов для решения уникальных проблем: сетевые задержки, отказы узлов, консистентность данных. Рассмотрим основные паттерны проектирования.

1. Паттерн Circuit Breaker

Предотвращает каскадные отказы при недоступности сервиса.

Состояния:

  • Closed — нормальное функционирование
  • Open — сервис недоступен, запросы блокируются
  • Half-Open — проверка восстановления

Пример:

from circuit_breaker import CircuitBreaker

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

try:
    response = cb.call(requests.get, 'http://external-api.com/data')
except CircuitBreakerListener:
    # API недоступен, используем fallback
    response = get_cached_data()

2. Паттерн Retry (Повторная попытка)

Повторяет операцию при временных ошибках.

Стратегии:

  • Exponential backoff — каждый раз ждём дольше (1s, 2s, 4s, 8s)
  • Linear backoff — линейное увеличение (1s, 2s, 3s)
  • Fixed delay — фиксированная задержка

Пример:

import time
import random

def retry_with_backoff(func, max_retries=3):
    for attempt in range(max_retries):
        try:
            return func()
        except Exception as e:
            if attempt == max_retries - 1:
                raise
            wait_time = 2 ** attempt  # exponential: 1, 2, 4
            wait_time += random.uniform(0, 1)  # jitter
            time.sleep(wait_time)

3. Паттерн Bulkhead (Переборка)

Изолирует ресурсы для предотвращения распространения отказов.

# Разные thread pools для разных операций
user_service_pool = ThreadPoolExecutor(max_workers=10)
order_service_pool = ThreadPoolExecutor(max_workers=20)

# Если user_service упал, order_service продолжает работать
user_service_pool.submit(get_user, user_id)
order_service_pool.submit(create_order, order_data)

4. Паттерн Timeout

Ограничивает время ожидания ответа от сервиса.

response = requests.get(
    'http://slow-api.com/data',
    timeout=5  # Макс 5 секунд
)

# Если медленнее — ConnectionTimeout исключение

5. Паттерн Bulkhead для Data

Разделяет данные между узлами (sharding).

Вместо одного Postgres:
PG-1: users 0-999
PG-2: users 1000-1999
PG-3: users 2000-2999

6. Паттерн CQRS (Command Query Responsibility Segregation)

Разделяет чтение (Query) и запись (Command).

Command:

class CreateUserCommand:
    def __init__(self, name, email):
        self.name = name
        self.email = email

command_bus.execute(CreateUserCommand("John", "john@example.com"))

Query:

class GetUserQuery:
    def __init__(self, user_id):
        self.user_id = user_id

user = query_bus.execute(GetUserQuery(123))  # из read-only replica

Преимущества:

  • Различная оптимизация для чтения и записи
  • Масштабирование независимо
  • Кеширование для queries

7. Паттерн Event Sourcing

Хранит не состояние, а историю событий.

# Вместо: users = {1: {name: "John", status: "active"}}
# Храним события:
events = [
    {"type": "UserCreated", "user_id": 1, "name": "John"},
    {"type": "UserEmailChanged", "user_id": 1, "email": "john@example.com"},
    {"type": "UserActivated", "user_id": 1},
]

# Текущее состояние = воспроизведение всех событий
def get_user_state(user_id):
    user = {}
    for event in get_events_for_user(user_id):
        if event["type"] == "UserCreated":
            user = {"id": event["user_id"], "name": event["name"]}
        elif event["type"] == "UserEmailChanged":
            user["email"] = event["email"]
        elif event["type"] == "UserActivated":
            user["status"] = "active"
    return user

Преимущества:

  • Полная история изменений
  • Можно восстановить состояние на любой момент времени
  • Аудит встроен
  • Легче отлаживать

8. Паттерн Saga (Распределённая транзакция)

Управляет долгоживущими транзакциями через микросервисы.

Варианты:

Choreography (хореография)

Order Service: create_order → публикует OrderCreated
          ↓
Payment Service: слушает OrderCreated → process_payment → публикует PaymentProcessed
          ↓
Inventory Service: слушает PaymentProcessed → reserve_items → публикует ItemsReserved
          ↓
Notification Service: слушает ItemsReserved → send_confirmation

Orchestration (оркестровка)

Order Saga Orchestrator:
1. Вызывает Payment Service
2. При успехе → вызывает Inventory Service
3. При успехе → вызывает Notification Service
4. При ошибке → запускает компенсацию (refund)

9. Паттерн Compensating Transaction (Компенсирующая транзакция)

Отменяет успешные операции при отказе.

class CreateOrderSaga:
    def execute(self):
        # Forward transaction
        payment_id = payment_service.charge($100)
        inventory_service.reserve_items(items)
        
        if notification_service.send() fails:
            # Compensation: отмена
            payment_service.refund(payment_id)
            inventory_service.unreserve_items(items)
            raise Exception("Order creation failed")

10. Паттерн Service Mesh

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

┌─────────────┐     ┌──────────────┐     ┌──────────────┐
│ User Svc    │     │ Order Svc    │     │ Payment Svc  │
└──────┬──────┘     └──────┬───────┘     └──────┬───────┘
       │sidecar            │sidecar             │sidecar
       ↓                   ↓                   ↓
    Envoy ────────────── Envoy ────────────── Envoy
       (Service Mesh)

Функции (Istio, Linkerd):

  • Load balancing
  • Retry & timeout
  • Circuit breaking
  • Traffic splitting
  • Monitoring & observability

11. Паттерн Strangler Fig

Постепенная замена монолита на микросервисы.

1. Новый сервис обёртывает старую функцию
2. Постепенно перенаправляем трафик
3. Полностью заменяем старую функцию

API Gateway
    ↓
    ├─ 90% → Old Monolith (User Service)
    └─ 10% → New Microservice (User Service v2)
    
    ... через месяц
    
API Gateway
    ↓
    ├─ 50% → Old Monolith
    └─ 50% → New Microservice
    
    ... через 2 месяца
    
API Gateway
    ↓
    └─ 100% → New Microservice

12. Паттерн API Gateway

Единая точка входа для всех клиентов.

Клиенты → API Gateway → маршрутизация
                ├→ User Service
                ├→ Order Service
                ├→ Payment Service
                └→ Notification Service

Функции:

  • Аутентификация
  • Rate limiting
  • Request/response transformation
  • Маршрутизация
  • Логирование

13. Паттерн Sidecar

Дополнительный контейнер для кроссовых задач.

Под в Kubernetes:
┌─────────────────────────────────┐
│ Application Container (User Svc)│
├─────────────────────────────────┤
│ Sidecar Container (Logging)     │
├─────────────────────────────────┤
│ Sidecar Container (Monitoring)  │
└─────────────────────────────────┘

Паттерны мониторинга и отладки

Distributed Tracing

Пользовательский запрос (request_id = "abc-123")
    ↓
API Gateway (trace: abc-123, span: api-1)
    ↓
User Service (trace: abc-123, span: user-1)
    ↓
Database (trace: abc-123, span: db-1)

Каждый сервис логирует с одним request_id

Инструменты: Jaeger, Zipkin, DataDog

Health Checks & Liveness Probes

@app.get("/health")
def health():
    if db.is_connected() and cache.is_connected():
        return {"status": "healthy"}
    else:
        return {"status": "unhealthy"}, 503

Значение для System Analyst

System Analyst должен:

  • Выбирать подходящие паттерны для архитектуры
  • Понимать trade-offs каждого паттерна
  • Проектировать отказоустойчивые системы
  • Планировать мониторинг и наблюдаемость
  • Документировать архитектуру паттернов
  • Обучать команду лучшим практикам
Какие знаешь паттерны для проектирования распределенных систем? | PrepBro