Каковы основные преимущества и сложности микросервисной архитектуры?

«Каковы основные преимущества и сложности микросервисной архитектуры?» — вопрос из категории Архитектура, который задают на 10% собеседований QA Тестировщик. Ниже — развёрнутый ответ с разбором ключевых моментов.

Ответ

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

  1. Независимое развертывание и масштабирование: Каждый сервис можно обновлять, масштабировать и перезапускать независимо от других. Это ускоряет delivery.
  2. Технологическая гетерогенность: Разные сервисы могут быть написаны на разных языках и использовать разные СУБД, что позволяет выбирать оптимальный стек для конкретной задачи.
  3. Улучшенная отказоустойчивость: Падение одного сервиса не должно приводить к полному краху системы, если реализована корректная обработка ошибок (circuit breakers, retries).
  4. Четкие границы ответственности: Упрощает понимание и поддержку кода, так как каждый сервис решает конкретную бизнес-задачу.

Сложности и недостатки:

  1. Распределенные системы: Появляются все сложности distributed computing: сетевые задержки, частичные отказы, необходимость обеспечения идемпотентности.
  2. Согласованность данных: Обеспечение ACID-транзакций невозможно. Требуется использовать паттерны итоговой согласованности (Saga, Event Sourcing, компенсирующие транзакции).
  3. Операционная сложность (Operational Overhead): Требуются мощные системы для оркестрации (Kubernetes), мониторинга, логирования, трассировки запросов и обнаружения сервисов.
  4. Сложность тестирования: Необходимо тестировать не только каждый сервис в изоляции (юнит-тесты), но и их взаимодействие (интеграционные, контрактные тесты).

Пример интеграционного теста для микросервиса:

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"]