Ответ
Преимущества:
- Независимое развертывание и масштабирование: Каждый сервис можно обновлять, масштабировать и перезапускать независимо от других. Это ускоряет delivery.
- Технологическая гетерогенность: Разные сервисы могут быть написаны на разных языках и использовать разные СУБД, что позволяет выбирать оптимальный стек для конкретной задачи.
- Улучшенная отказоустойчивость: Падение одного сервиса не должно приводить к полному краху системы, если реализована корректная обработка ошибок (circuit breakers, retries).
- Четкие границы ответственности: Упрощает понимание и поддержку кода, так как каждый сервис решает конкретную бизнес-задачу.
Сложности и недостатки:
- Распределенные системы: Появляются все сложности distributed computing: сетевые задержки, частичные отказы, необходимость обеспечения идемпотентности.
- Согласованность данных: Обеспечение ACID-транзакций невозможно. Требуется использовать паттерны итоговой согласованности (Saga, Event Sourcing, компенсирующие транзакции).
- Операционная сложность (Operational Overhead): Требуются мощные системы для оркестрации (Kubernetes), мониторинга, логирования, трассировки запросов и обнаружения сервисов.
- Сложность тестирования: Необходимо тестировать не только каждый сервис в изоляции (юнит-тесты), но и их взаимодействие (интеграционные, контрактные тесты).
Пример интеграционного теста для микросервиса:
import requests
import pytest
SERVICE_URL = "http://user-service:8080"
def test_get_user_by_id():
"""Тест эндпоинта получения пользователя."""
user_id = 1
response = requests.get(f"{SERVICE_URL}/users/{user_id}", timeout=3)
assert response.status_code == 200, f"Ожидался 200 OK, получен {response.status_code}"
user_data = response.json()
assert user_data["id"] == user_id
assert "name" in user_data # Проверка обязательного поля
assert "email" in user_data
# Проверка формата email (базовая валидация)
assert "@" in user_data["email"]