Как ответить
Архитектура системы — это описание её структурных элементов, их обязанностей и связей. Если отвечать кратко каждый проект уникален, но есть повторяющиеся паттерны. Я разделяю архитектуру на несколько слоёв: инфраструктурный, сетевой, прикладной. Дальше расскажу на примере типового микросервисного приложения для обработки заказов.
Инфраструктура — это база. У нас кубернетес кластер (EKS), managed PostgreSQL и Redis для кеша. Все развёрнуто через Terraform. Один DB instance на 4 vCPU, 16GB RAM, храним snapshot каждые 6 часов. Redis кластеров два — один для сессий, второй для очередей (через Redis Streams).
Сеть — VPC с публичной и приватной подсетями. API Gateway в публичной подсети принимает запросы и роутит через внутренние ALB к сервисам. mTLS между сервисами. Раньше был service mesh, но для небольшой команды из 10 человек проще явно пробросить mTLS через Envoy sidecar — меньше оверхед по управлению.
Прикладной слой — микросервисы. Основные три: сервис заказов (Orders API), сервис платежей (Payments), сервис нотификаций (Notifications). Orders API общается с Payments через gRPC, та же история с нотификациями. Для асинхронных операций используем очередь на Redis Streams — например, после создании заказа отправляем событие "order.created" в стрим, обработчики подхватывают. Ошибки — retry с экспоненциальной задержкой и Dead Letter Queue.
Хранилище: PostgreSQL для Orders (master-slave, автофейловер через Patroni), S3 для файлов (чеки, PDF счетов), Elasticsearch для поиска по заказам (пишем в него синхронно через сервис нотификаций).
CI/CD: GitHub Actions, Docker образы собираются в ECR, деплой через ArgoCD с canary стратегией. Health checks (readiness + liveness) обязательны. Один нездоровый pod — ArgoCD автоматом откатывается.
Мониторинг: Prometheus собирает метрики (latency, error rate, request count), Grafana для дашбордов, PagerDuty на критичное (>500ms p99) падение. Logs — Loki, distributed traces — Jaeger. Без трейсинга непонятно, кто тормозит, когда заказ падает на 2 секунды.
Главный принцип: каждый сервис владеет своей частью домена. Заказ — это не транзакция с платежом, а событие, которое потом обрабатывается. Это снижает coupling и позволяет платежному сервису падать независимо — пользователь увидит "ожидание платежа", а не 500 ошибку.