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

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

Ответ

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

  • Независимое масштабирование: Каждый сервис можно масштабировать отдельно в зависимости от нагрузки.
  • Технологическая гибкость: Разные сервисы могут быть реализованы на наиболее подходящих языках и фреймворках.
  • Отказоустойчивость: Сбой одного сервиса не приводит к полному отказу всей системы.
  • Независимость команд: Команды могут разрабатывать, тестировать и развертывать свои сервисы автономно.
  • Лёгкость внедрения изменений: Обновление одного сервиса не требует пересборки всей системы.

Недостатки:

  • Высокая сложность: Требуются дополнительные инфраструктурные компоненты: оркестратор (Kubernetes), service mesh, централизованное логирование и мониторинг.
  • Накладные расходы на связь: Межсервисная коммуникация (REST, gRPC, сообщения) добавляет задержки и требует обработки сетевых ошибок.
  • Сложность обеспечения согласованности данных: Транзакции, охватывающие несколько сервисов, требуют сложных паттернов (Saga, Event Sourcing).
  • Сложность тестирования: End-to-end тестирование становится труднее из-за распределённой природы системы.

Пример обработки частичного отказа:

import requests
from circuitbreaker import circuitbreaker

@circuitbreaker(failure_threshold=5, recovery_timeout=60)
def get_data_from_service_b():
    """Вызов другого сервиса с использованием Circuit Breaker."""
    try:
        response = requests.get("http://service-b/api/data", timeout=2)
        response.raise_for_status()
        return response.json()
    except (requests.exceptions.RequestException, requests.exceptions.Timeout):
        # Логика fallback: вернуть кэшированные данные или значение по умолчанию
        log.error("Service B недоступен, используется fallback")
        return get_cached_data()  # Стратегия отказоустойчивости

Почему это важно: Паттерн Circuit Breaker предотвращает "каскадные отказы", когда повторные вызовы падающего сервиса истощают ресурсы вызывающей стороны.