Ответ
Распределённый монолит — это архитектурный антипаттерн, при котором система состоит из нескольких сервисов (как в микросервисной архитектуре), но они сильно связаны между собой и не могут развертываться или изменяться независимо. Такая система сочетает в себе сложности распределенных систем и проблемы с зависимостями, свойственные монолиту.
Ключевые признаки:
- Сильная связанность (Tight Coupling): Сервисы часто делают синхронные вызовы друг к другу. Отказ одного сервиса каскадно приводит к отказу других.
- Общая база данных: Несколько сервисов работают с одной и той же схемой или базой данных, что делает невозможным независимое изменение структуры данных.
- Сложное развертывание: Для выпуска новой функциональности требуется одновременное развертывание нескольких сервисов.
- Низкая автономность команд: Команды не могут работать над своими сервисами независимо друг от друга.
Пример сильной связанности через синхронные вызовы:
Представим, что сервис Orders
для создания заказа должен синхронно получить данные из сервиса Users
и Products
.
# Код в сервисе Orders
import requests
def create_order(user_id, product_id):
# 1. Синхронный вызов к сервису Users
user_response = requests.get(f"http://users-service/users/{user_id}")
if user_response.status_code != 200:
raise Exception("User service is unavailable")
# 2. Синхронный вызов к сервису Products
product_response = requests.get(f"http://products-service/products/{product_id}")
if product_response.status_code != 200:
raise Exception("Product service is unavailable")
# ... логика создания заказа ...
return {"status": "created"}
В этом примере сервис Orders
не может работать, если Users
или Products
недоступны.
Как избежать:
- Слабая связанность: Использовать асинхронную коммуникацию через брокеры сообщений (например, RabbitMQ, Kafka).
- Отдельные базы данных: Каждый сервис должен владеть своими данными.
- Четкие границы контекстов (Bounded Contexts): Проектировать сервисы на основе бизнес-доменов (принцип DDD).