Какие условия в приложении нужно соблюсти, чтобы оно было микросервисом

«Какие условия в приложении нужно соблюсти, чтобы оно было микросервисом» — вопрос из категории Архитектура и DevOps-практики, который задают на 23% собеседований Devops Инженер. Ниже — развёрнутый ответ с разбором ключевых моментов.

Ответ

Чтобы приложение считалось микросервисом, оно должно соответствовать ряду ключевых принципов, которые напрямую влияют на работу DevOps:

  1. Строгая автономность и независимое развертывание: Каждый микросервис должен иметь собственный цикл разработки и развертывания. Это означает отдельный репозиторий кода, отдельный конвейер CI/CD и возможность быть развернутым без необходимости деплоить или перезапускать другие сервисы. На практике мы добивались этого, упаковывая каждый сервис в отдельный Docker-образ и развертывая его в Kubernetes как независимый Deployment.

  2. Изоляция данных: У сервиса должна быть своя, приватная база данных или схема. Прямой доступ к БД одного сервиса из другого запрещен. Обмен данными происходит только через API. Например, сервис "Заказы" и сервис "Оплата" имеют свои PostgreSQL-базы. Для согласованности данных между ними используется асинхронное взаимодействие через события (Kafka).

  3. Ориентация на бизнес-домен (ограниченный контекст): Сервис должен решать одну четкую бизнес-задачу (например, "Управление аутентификацией пользователей", "Каталог товаров"). Это делает его заменяемым и понятным.

  4. Слабая связность через четкие API: Взаимодействие между сервисами происходит через хорошо определенные, версионируемые API (чаще всего REST/HTTP или gRPC) или асинхронно через брокеры сообщений (RabbitMQ, Kafka). Контракты API описываются с помощью OpenAPI/Swagger или protobuf-файлов.

  5. Устойчивость к отказам (Resilience): Сервис должен быть спроектирован так, чтобы отказы в зависимых сервисах не приводили к его полному падению. Это достигается паттернами вроде Circuit Breaker, Retry, Fallback и Timeout. В нашем стеке мы использовали библиотеку resilience4j в Java-сервисах и настройки в sidecar-прокси (Istio) для управления трафиком.

Пример DevOps-артефактов для микросервиса "User Service":

  • Dockerfile: Для создания образа.
  • Helm chart (user-service/): Для развертывания в k8s.
  • CI/CD pipeline (.gitlab-ci.yml): Который запускает тесты, собирает образ, сканирует его на уязвимости и деплоит в staging/prod.
  • Настройки мониторинга: Отдельные дашборды в Grafana и правила алертинга в Prometheus для метрик этого конкретного сервиса (латентность, ошибки, RPS).
# Пример фрагмента манифеста k8s, подчеркивающего автономность
apiVersion: apps/v1
kind: Deployment
metadata:
  name: user-service
spec:
  replicas: 3
  selector:
    matchLabels:
      app: user-service
  template:
    metadata:
      labels:
        app: user-service
    spec:
      containers:
      - name: user-service
        image: registry.example.com/user-service:v1.2.5 # Свой образ
        env:
        - name: DB_CONNECTION_STRING
          valueFrom:
            secretKeyRef: # Свои секреты для своей БД
              name: user-service-db-secret
              key: connection-string
---
apiVersion: v1
kind: Service
metadata:
  name: user-service
spec:
  selector:
    app: user-service
  ports:
  - port: 80
    targetPort: 8080