Перейти к содержимому

Microservices vs Monolith: спектр архитектур

Зачем знать: “Microservices vs monolith” — главный архитектурный холивар 2010-2020. К 2026 году рынок остыл: ясно, что между монолитом и микросервисами есть весь спектр (modular monolith, distributed monolith — anti-pattern, miniservices, microservices, nanoservices). Middle Go-разработчик должен уметь оценить: моноолит правильное решение для стартапа из 10 человек, или нужно дробить уже? Когда modular monolith лучше? Что такое distributed monolith и почему он хуже обоих?

  1. Концепция: спектр архитектур
  2. Глубже: modular monolith, Strangler Fig, anti-patterns
  3. Gotchas
  4. Real cases
  5. Вопросы (20)
  6. Practice
  7. Источники

Архитектура — это не binary choice “монолит или микросервисы”. Это спектр:

Monolith → Modular Monolith → Miniservices → Microservices → Nanoservices
↓ ↓ ↓ ↓
single deploy single deploy несколько серв. много серв. too small
anti-pattern
Distributed Monolith
(anti-pattern):
много сервисов,
но deploy together

Один процесс, одна codebase, один deploy.

[Single binary / process]
├── handlers/
├── services/
├── repositories/
└── domain models

Pros:

  • Простота: один git repo, один CI/CD pipeline, один runtime.
  • Atomicity: транзакции через БД, нет distributed problems.
  • Refactoring: легко двигать код между модулями.
  • Debugging: один процесс, один stack trace.
  • Performance: in-process calls вместо network.

Cons:

  • Scaling: масштабируется только вертикально, либо весь монолит горизонтально (даже если узкое место — один module).
  • Tech stack: один язык, одна runtime.
  • Deploy: каждое изменение требует deploy всего.
  • Team coordination: 50+ инженеров на одной codebase — merge conflicts, longer reviews.
  • Blast radius: bug в одном модуле — падает всё.

Когда монолит ок:

  • Стартап, MVP, прототип.
  • Команда < 10 человек.
  • Domain ещё не понят (microservices boundaries неясны).
  • Performance critical (low-latency in-process calls).

Антипример мнения: “Микросервисы — best practice.” Нет. DHH (Basecamp, Hey.com) ушёл от микросервисов обратно к монолиту в 2022. Shopify публично использует “majestic monolith”. Stack Overflow обслуживает 6B запросов в месяц на small fleet of monolithic servers.

Один процесс, но строгие модули с явными границами.

[Single binary]
├── modules/
│ ├── payment/
│ │ ├── api/ (public interface)
│ │ ├── internal/ (private logic)
│ │ └── models/
│ ├── order/
│ └── customer/
└── main.go

Между модулями — internal API (Go interfaces), не direct access к internals.

Pros монолита, плюс:

  • Чёткие boundaries — легче понять, поменять.
  • Independent development по модулям.
  • Migration path к microservices: модуль уже изолирован, его можно вытащить.
  • Single deploy (простота).
  • Atomic refactoring across modules.

Cons:

  • Требует дисциплины (Go-linter проверяет imports между модулями).
  • Один runtime, один tech stack.
  • Скорость deploy зависит от общего CI/CD.

Реализация в Go:

  • Use internal package (payment/internal/) — Go enforces visibility.
  • One main, multiple sub-packages.
  • Tools: go-cleanarch, arch-go для проверки правил.

Несколько процессов, каждый — независимый сервис.

[Order Service] ←→ [Payment Service] ←→ [Notification Service]
Go, Go, Python
Postgres Postgres+Redis RabbitMQ

Pros:

  • Independent scaling.
  • Independent deploy.
  • Tech stack per service.
  • Team ownership (Conway’s law).
  • Fault isolation (один сервис не валит другие, при правильных resilience patterns).

Cons:

  • Distributed complexity: network failures, latency, consistency.
  • Operations: K8s, service mesh, observability stack.
  • Debugging: trace через 5 hops через 5 сервисов.
  • Eventual consistency.
  • Schema evolution через несколько сервисов.

“Any organization that designs a system… will produce a design whose structure is a copy of the organization’s communication structure.” — Melvin Conway, 1967.

Применение: структура сервисов отражает структуру команд. Если команды раздроблены — микросервисы естественны. Если команда одна — монолит.

Inverse Conway Maneuver: организуй команды так, как хочешь, чтобы выглядела архитектура.

  • Multiple teams (>3 команды по 5-10 человек).
  • Different scaling needs: search service нужен 100 instances, payment — 5.
  • Different tech stacks: ML на Python, real-time на Go, batch на Spark.
  • Independent release cycles: разные команды деплоят разное.
  • Different SLAs: payment 99.99%, analytics 99%.
  • Compliance isolation: PCI-DSS только для billing service.

Hidden costs:

  • Network latency: in-process call ~ns, gRPC ~1ms. 10 hops = 10ms minimum.
  • Network reliability: TCP не идеален, ретраи нужны везде.
  • Distributed transactions: Saga, outbox, eventual consistency. Сложно.
  • Service discovery: Consul, etcd, Kubernetes Service.
  • Observability: distributed tracing (Jaeger, Tempo), aggregated logs (Loki, ELK), metrics (Prometheus).
  • DevOps cost: K8s expertise, CI/CD per service, service mesh.
  • Data consistency: eventual, conflicts, reconciliation.
  • Schema evolution: versioning, backwards compat между сервисами.
  • Testing: unit + integration + contract + E2E.

Estimated cost: 30-50% engineering overhead для same business functionality.

Migration legacy → new (часто monolith → microservices).

Идея от banyan tree: новое растение обрастает старое, постепенно его душит. В коде:

[Old Monolith]
[Proxy/Facade] ←─── route some endpoints to new
[New Microservice]

Шаги:

  1. Поставить proxy перед monolith.
  2. Извлечь endpoint X в новый микросервис.
  3. Proxy роутит X → new, остальное → monolith.
  4. Повторить для других endpoints.
  5. Monolith постепенно усыхает.

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

  • Incremental, не big bang rewrite.
  • Old + new работают параллельно.
  • Можно откатить, если new фейлится.

Pitfalls:

  • Долго (годы).
  • Двойная поддержка во время.
  • Shared database — proxy не помогает.

Симптомы:

  • Много сервисов, но deploy together (нельзя один без других).
  • Tight coupling: A синхронно вызывает B вызывает C → если C упал, A падает.
  • Shared database между сервисами.
  • Changes требуют координации между командами на каждый release.

Это хуже монолита: сложность распределённой системы без её преимуществ.

Признаки:

  • “Сегодня выкатываем feature X — нужно координировать 5 команд.”
  • “Не можем запустить локально без всех 12 сервисов.”
  • “Изменение API в одном сервисе ломает 5 других.”

Решение:

  • Async messaging вместо sync calls (где возможно).
  • Database per service.
  • Versioned APIs.
  • Service contracts (Pact, consumer-driven contracts).

Микросервисы слишком мелкие. “Каждая функция — отдельный сервис.”

Признаки:

  • Сервис делает одно простое CRUD на одну таблицу.
  • Больше сервисов чем разработчиков.
  • Inter-service calls для каждой бизнес-операции.

Проблемы:

  • Network overhead доминирует над работой.
  • Координация для любого изменения.
  • Observability ад: тысячи нод в трейсе.

Правило большого пальца (Kelsey Hightower): “Microservice should be small enough that 2 engineers can own it, but not so small that it’s a function.”

Эмпирические правила:

  • “Two-pizza team”: команда, которая помещается за двумя пиццами (~6-10 человек). Каждая команда владеет одним сервисом (Amazon).
  • “Two-week rewrite”: сервис достаточно мал, что можно переписать за 2 недели.
  • “Bounded context” (DDD): один сервис = один bounded context.

Sync (request-reply):

  • HTTP REST, gRPC.
  • Простой, но caller блокируется.
  • Используй для: query (read), critical commands где нужен ответ.

Async (events):

  • Kafka, RabbitMQ, NATS.
  • Слабая связь, fault-tolerant.
  • Используй для: notifications, eventual workflows, fan-out.

Правило: sync для query, async для command (events).

Bad: [Order Service] --sync POST→ [Inventory] --sync POST→ [Shipping]
Good: [Order Service] → publishes OrderCreated event
[Inventory] subscribes, reserves
[Shipping] subscribes, schedules

В sync chain если один упал — все падают. В async chain каждый работает независимо.


project/
├── cmd/
│ └── app/
│ └── main.go
├── internal/
│ ├── modules/
│ │ ├── payment/
│ │ │ ├── api/ # public interface (interfaces, DTOs)
│ │ │ │ └── api.go
│ │ │ ├── internal/ # private (Go enforces visibility)
│ │ │ │ ├── service.go
│ │ │ │ └── repository.go
│ │ │ └── module.go # wire dependencies
│ │ ├── order/
│ │ └── customer/
│ ├── platform/ # shared infrastructure
│ │ ├── db/
│ │ ├── logger/
│ │ └── auth/
│ └── app/ # composition root
│ └── app.go
└── pkg/ # public для external use (rare)

Правила:

  • Module A может импортировать только modules/B/api/, не modules/B/internal/.
  • Go enforce’ит через internal/ package.
  • internal/modules/payment/internal/ доступно только из internal/modules/payment/....

API между модулями:

internal/modules/payment/api/api.go
package paymentapi
type Service interface {
Charge(ctx context.Context, userID string, amount int64) (TransactionID, error)
GetTransaction(ctx context.Context, txID TransactionID) (*Transaction, error)
}
// internal/modules/order/internal/service.go
package order
import paymentapi "myapp/internal/modules/payment/api"
type OrderService struct {
payment paymentapi.Service
}
func (s *OrderService) PlaceOrder(...) {
s.payment.Charge(ctx, userID, amount)
}

При миграции к microservices: реализация paymentapi.Service меняется с in-process на gRPC client. Контракт остаётся.

payment-service/
├── cmd/
│ └── server/
│ └── main.go
├── internal/
│ ├── domain/ # сущности, value objects
│ ├── application/ # use cases
│ ├── infrastructure/
│ │ ├── repository/ # PostgreSQL impl
│ │ ├── messaging/ # Kafka producer/consumer
│ │ └── client/ # gRPC clients для других сервисов
│ ├── api/
│ │ ├── grpc/
│ │ └── http/
│ └── config/
├── proto/ # gRPC contracts
├── migrations/ # SQL migrations
├── Dockerfile
├── go.mod
└── deploy/
└── kubernetes/

Принцип: каждый микросервис владеет своей БД. Никакие другие сервисы не имеют direct DB access.

Pros:

  • Schema evolution без координации.
  • Right tool for the job (Order — Postgres, Search — Elastic, Cache — Redis).
  • Failure isolation.

Cons:

  • Joins через сервисы (через API/events).
  • Distributed transactions сложны.
  • Data duplication (одни данные хранятся в нескольких сервисах).

Anti-pattern: “Shared DB между сервисами.” Это создаёт coupling сильнее, чем у monolith — изменение схемы ломает несколько сервисов.

Sync через gRPC:

service PaymentService {
rpc Charge(ChargeRequest) returns (ChargeResponse);
rpc GetTransaction(GetTransactionRequest) returns (GetTransactionResponse);
}
conn, _ := grpc.Dial("payment-service:9090", grpc.WithTransportCredentials(insecure.NewCredentials()))
client := pb.NewPaymentServiceClient(conn)
resp, err := client.Charge(ctx, &pb.ChargeRequest{UserId: "u1", Amount: 100})

Async через Kafka:

// Producer (Order Service)
producer.Send(ctx, &kafka.Message{
Topic: "order-events",
Key: []byte(orderID),
Value: encode(OrderCreatedEvent{...}),
})
// Consumer (Inventory Service)
for msg := range consumer.Messages() {
event := decode(msg.Value)
handleOrderCreated(event)
consumer.MarkMessage(msg, "")
}

См. отдельную тему. Кратко: chain of compensating actions.

Когда выделить новый сервис?

  1. Different scaling needs: один компонент требует разной capacity.
  2. Different team ownership: два team фокусируются на разном.
  3. Different SLA: один критичен, другой нет.
  4. Different tech stack: ML нужен Python, real-time нужен Go.
  5. Different change frequency: один меняется каждый день, другой — раз в квартал.
  6. Different compliance: PCI/HIPAA для одного, нет для другого.

Если ни одного из этих — не дроби. Cohesive features вместе.

Шаги:

  1. Спроектируй желаемую архитектуру.
  2. Реструктурируй команды так, чтобы они владели сервисами 1:1.
  3. Архитектура естественно эволюционирует в нужное.

Пример:

  • Хотим payment, order, inventory как отдельные сервисы.
  • Создаём 3 команды: Payment Team, Order Team, Inventory Team.
  • Каждая команда деплоит свой сервис, владеет API.
  • Конвэйс заработал на тебя.

Pattern 1: Strangler Fig (см. выше).

Pattern 2: Branch by Abstraction:

  • Внутри monolith создай abstraction layer над данными.
  • Реализация может быть локальной или удалённой.
  • Переключай feature flag для миграции.

Pattern 3: Parallel Run:

  • Запусти новый сервис параллельно со старым.
  • Дублируй запросы в оба.
  • Сравнивай ответы.
  • Когда уверен — переключи.

Pattern 4: Database Migration:

  • Изначально shared DB.
  • Сервис читает/пишет в shared DB.
  • Параллельно создаём private DB и реплицируем.
  • Переключаем чтение на private DB.
  • Прекращаем запись в shared DB.

В микросервисной архитектуре нормально иметь:

  • Order service — PostgreSQL.
  • Cart service — Redis (TTL автоматически).
  • Search — Elasticsearch.
  • Analytics — ClickHouse.
  • Files — S3.

Каждый сервис выбирает оптимальное хранилище.

В monolith это сложнее: один процесс должен работать с несколькими БД, scaling сложен.

См. файл 23 (API Gateway / Service Mesh). Кратко: Istio/Linkerd добавляют mTLS, observability, traffic management без изменения кода сервисов.


⚠️ “Микросервисы — best practice.” Нет. Контекст важен. Большинство стартапов должно начинать с монолита.

⚠️ Преждевременное дробление. Если boundaries не понятны, дробление создаёт frozen boundaries — менять их потом дорого.

⚠️ Distributed monolith. Микросервисы без autonomy = хуже монолита. Симптомы: shared DB, sync chains, deploy together.

⚠️ Nanoservices. Сервис на 100 строк кода — overhead network/observability больше пользы.

⚠️ Shared library hell. Одна shared lib импортируется всеми сервисами → её bump требует деплой всех. Альтернатива: contract testing.

⚠️ Versioning API. /v1/users vs /v2/users. Если не делать — breaking changes сломают консьюмеров. Если делать — больше maintenance.

⚠️ Distributed tracing забыли. В микросервисах без tracing дебаг — мука. Внедряй OpenTelemetry с первого дня.

⚠️ Local dev pain. Если для запуска “hello world” нужны 12 сервисов + Kafka + Redis + Postgres + Elastic — productivity tanks. Используй docker-compose, или mocks, или devcontainers.

⚠️ Cascading failures. Если A sync calls B calls C calls D, и D медленный — все цепочки висят. Circuit breakers + async patterns.

⚠️ Cost of microservices. RAM ×N, CPU ×N, network egress, observability. Иногда дешевле big monolith на больших box.

⚠️ Team velocity при микросервисах. Часто измеряется через “сколько фич в спринт”. Микросервисы могут замедлить начальные спринты, но ускорить долгосрочные.

⚠️ Premature optimization для scale. “Через 5 лет у нас будет 100M users, давайте microservices сразу.” Нет. Дойди до 10K users на монолите, потом рефактори.

⚠️ Refactoring через сервисы дорого. Внутри monolith — move file. Через сервисы — координация APIs, миграция данных, синхронизация deploy.

⚠️ Modular monolith требует дисциплины. Без enforcement (linters, code review) границы размываются → “ball of mud”.

⚠️ Microservices без CI/CD = катастрофа. Каждый сервис должен иметь свой автоматический pipeline, иначе deploy 50 сервисов вручную невозможен.

⚠️ Schema versioning в events. Если producer изменил схему, consumer ломается. Используй schema registry (Confluent, Karapace) + backwards compat правила.


Monzo Bank — microservices. 1500+ микросервисов. Внутренняя платформа на Go. Cassandra, Kafka. Сильная investment в platform team. Это не для всех.

Shopify — modular monolith (“Majestic Monolith”). Большая часть Shopify — modular monolith на Rails. После 12+ лет роста — всё ещё monolith. Извлекли несколько critical services (Inventory, Payments).

Netflix — microservices. Pioneer. Тысячи сервисов. Open sourced Hystrix, Eureka, Zuul. Эстафету подхватили service mesh (Istio).

DHH / 37signals / Basecamp — back to monolith. В 2022 объявили “leaving the cloud.” Сервисы стали обратно одним монолитом. Простота и cost.

Uber — миграция в разные стороны. 2008: Python monolith. 2014-2018: ~2000 микросервисов. 2020+: “Domain-Oriented Microservice Architecture (DOMA)” — группировка микросервисов в домены, упрощение.

Amazon — “two-pizza teams”. Каждая команда владеет своим сервисом. AWS — extreme microservices. Внутренние сервисы — тысячи.

Google — миксы. Borg/Kubernetes — internal microservices. Но некоторые продукты (Search Frontend) — гигантские монолиты.

Facebook (Meta) — monolith for years. PHP/Hack monolith долго. Извлекли некоторые сервисы (News Feed ranking).

Stack Overflow — monolith. Один большой ASP.NET monolith. 6B запросов в месяц. Несколько hand-tuned серверов. Жан-вертикальное масштабирование.

Spotify — squad model + microservices. Squads (small teams) владеют сервисами. ~1000 сервисов. Сильная investment в Backstage (developer portal).

Mercedes Benz — modular monolith → microservices. Платформа постепенно перешла. Сначала boundaries through modules, затем вытащили в сервисы.

Tinkoff Bank — microservices. Сильное технологическое подразделение. Микросервисы на Go (большая часть), Kafka, K8s.

Yandex.Taxi — microservices. ~1500 сервисов. Полностью C++ (исторически), часть Python. Облако Y.Cloud — внутренний deploy.

WhatsApp до Facebook — monolith. 50 человек обслуживали 900M пользователей. Erlang monolith. Это extreme case “majestic monolith”.

Etsy — monolith and beyond. Большой PHP monolith много лет. Migration на JVM/microservices для специфичных областей. Не всё дробили.

Twitter — initial monolith → microservices. Ruby on Rails monolith (“fail whale” era 2008-2010). Перешли на JVM + microservices (Scala). Сейчас X (Twitter) ещё больше микросервисов.

Khan Academy — Python monolith. Сильно одна codebase. Извлекли единичные сервисы. Простота вторична — образовательные продукты vs scale.

Yandex.Practikum — modular monolith. Modular monolith с микросервисами для специфичных областей (ML, video processing). Не extreme microservices.

Capital One — domain-oriented services. Не строго микросервисы, а сервисы по domain boundaries. Migration с mainframe legacy через Strangler Fig.

ING Bank — microservices. Squads и микросервисы. Один of pioneers banking microservices. Heavy investment в platform.

Etsy backend для frontend (BFF). Pattern adoption: BFF для mobile разный от web. Aggregation для mobile.

HEY.com email — back to monolith. DHH-led проект. Single monolith, deployed simply. Демонстрация anti-microservices мысли.

HashiCorp — Go microservices. HashiCorp products (Terraform, Vault, Consul, Nomad) — каждый microservice, но architecturally они тоже monoliths внутри. Composition external.

Modular monolith → microservices migration checklist:

  1. Идентифицировать bounded context (DDD).
  2. Удостовериться module имеет clear API.
  3. Дать ему свою БД (separate schema внутри monolith).
  4. Извлечь в отдельный процесс.
  5. Replace in-process call на gRPC/HTTP.
  6. Database migration (если общая).

Сосуществование monolith + microservices. Realistic: большинство компаний имеют hybrid. Core monolith + микросервисы вокруг для новых features или критичных по scale частей.

Cost of “doing microservices wrong”. Распространённый case: компания нанимает много инженеров, дробит на сервисы, но не строит platform (CI/CD, observability, service mesh). Результат: chaos, slow delivery, on-call hell.


Q1: Что такое монолит? A: Один процесс, одна codebase, один deploy. Все компоненты приложения работают вместе в одном runtime. Простота, но scaling/deploy ограничения.

Q2: Когда монолит — правильный выбор? A: Стартап, MVP, маленькая команда (<10), domain ещё не понят, performance-critical workload. WhatsApp обслуживал 900M users с 50 инженерами на monolith.

Q3: Что такое modular monolith? A: Монолит с строгими модулями и явными API между ними. Преимущества monolith (simplicity) + микросервисов (clear boundaries). Migration path.

Q4: Чем microservices отличаются от просто разделения на сервисы? A: Microservices — independent deploy, independent data store, loose coupling, owned by separate teams. Просто разделение без этих свойств — distributed monolith.

Q5: Что такое distributed monolith и почему он плох? A: Много сервисов, но deploy together, sync chains, shared DB. Сложность distributed + отсутствие преимуществ microservices. Хуже монолита.

Q6: Что такое nanoservices? A: Микросервисы слишком мелкие (каждая функция — сервис). Overhead network/observability больше пользы. Anti-pattern.

Q7: Объясните Conway’s Law. A: Архитектура системы отражает структуру коммуникации команд. Раздробленные команды → микросервисы естественны. Одна команда → монолит. Inverse maneuver: структурируй команды под желаемую архитектуру.

Q8: Когда оправданы микросервисы? A: Multiple teams (>3 команды), independent scaling, different tech stacks, different SLAs/compliance, independent release cycles. Минимум одно из этих должно быть.

Q9: Каковы скрытые costs микросервисов? A: Network latency, distributed transactions, observability, DevOps cost, schema evolution. Эстимат: 30-50% engineering overhead.

Q10: Что такое Strangler Fig pattern? A: Migration legacy → new. Поставить proxy. Постепенно переносить endpoints в новый сервис. Old + new в parallel. Eventually old retired.

Q11: Какие коммуникации между сервисами? A: Sync (HTTP/gRPC) для query, critical commands с нужным ответом. Async (Kafka/NATS/RabbitMQ) для events, notifications, eventual workflows. Правило: sync для query, async для command.

Q12: Что такое “database per service”? A: Каждый микросервис владеет своей БД. Никто другой не имеет direct DB access. Schema evolution без координации. Joins через API/events.

Q13: Можно ли иметь shared DB между микросервисами? A: Технически да, на практике это distributed monolith. Schema change ломает несколько сервисов. Sharing through service API only.

Q14: Какой размер сервиса оптимален? A: “Two-pizza team owns it” (6-10 человек). “Two-week rewrite”. Один bounded context (DDD). Не функция, не монолит — между.

Q15: Polyglot persistence — что это? A: В микросервисной архитектуре разные сервисы используют разные БД (Postgres, Redis, Elastic, ClickHouse). Right tool for the job. В монолите сложнее.

Q16: Что такое Inverse Conway Maneuver? A: Реструктурировать команды под желаемую архитектуру. Если хочешь 3 микросервиса — создай 3 команды по 1 сервису. Архитектура естественно эволюционирует.

Q17: Сколько сервисов это много? A: Уравнение: сервисов > людей → проблемы maintenance. Уравнение: сервисов > 3× команд → дробление избыточное. Monzo (1500) — extreme case с большим platform investment.

Q18: Что такое branch by abstraction? A: Migration pattern: внутри monolith создать abstraction layer. Реализация может переключаться (in-process или remote). Feature flag для миграции.

Q19: Зачем contract testing между сервисами? A: Гарантия совместимости API между producer и consumer. Без E2E запуска. Pact, Spring Cloud Contract. Защита от breaking changes.

Q20: Когда перейти с монолита на микросервисы? A: Симптомы: команда >20, deploy задерживается из-за координации, разные scaling needs очевидны, разные tech stacks нужны. Не делать преждевременно.

Q21: Modular monolith vs microservices — когда что? A: Modular monolith — simplicity деплоя + clear boundaries. Microservices — independent scaling/deploy + tech stack diversity, но цена. Modular monolith — отличная отправная точка.

Q22: Что делать если у вас “distributed monolith”? A: Шаг 1: identify cause — shared DB, sync chains, deploy coupling. Шаг 2: database per service. Шаг 3: async messaging. Шаг 4: versioned APIs. Постепенно decouple.

Q23: Как Conway’s Law влияет на архитектуру? A: Структура коммуникации команд определяет архитектуру системы. Раздробленные команды → микросервисы. Одна команда → monolith. Use Inverse Conway Maneuver для контроля.

Q24: Polyglot persistence — pros & cons? A: Pros: right tool per service (Redis for cache, ES for search, Postgres for transactions). Cons: больше БД для maintenance, dev complexity.

Q25: Когда использовать nanoservices можно? A: Почти никогда в business apps. FaaS (Lambda) для очень специфичных задач (image resize, webhook handler). Не для general microservices.


  1. Реализуй modular monolith на Go. 3 модуля (Order, Payment, Customer), каждый со своей internal/. API через interfaces. Используй linter для проверки imports.

  2. Strangler Fig симуляция. Создай “legacy” monolith с 3 endpoints. Добавь proxy (chi). Извлеки один endpoint в новый сервис. Покажи, что proxy роутит на новый.

  3. Извлечение модуля в сервис. Из modular monolith вытащи Payment module в отдельный сервис. Замени in-process call на gRPC. Сравни latency.

  4. Сервис с polyglot persistence. Order service: PostgreSQL для orders, Redis для cart, Elasticsearch для search. Покажи sync data между ними.

  5. Distributed monolith detection. Запусти 3 сервиса с sync chain (A → B → C). Покажи каскадный fail. Затем переделай через events. Сравни.

  6. Contract test с Pact. Producer-consumer contracts. Schema change в producer должен ломать contract test.

  7. Database per service migration. Изначально shared DB. Реализуй replication в private DB. Переключи чтение/запись.

  8. Сравни operational complexity. Поставь monitoring (Prometheus + Grafana + Jaeger) на monolith и на 5-service microservices. Время на запуск, размер дашбордов.

  9. Inverse Conway Maneuver симуляция. Опиши команды и сервисы. Покажи, как структура команд диктует API контракты.

  10. Cost analysis. Эстимируй cost (cloud bill, dev time) для same feature на monolith vs 3-service microservices vs 10-service.

  11. Команда + архитектура. Опиши hypothetical компанию (50 инженеров, 8 продуктов). Какая структура команд и сервисов?

  12. Latency analysis. Запусти monolith и распределённый equivalent. Замерь p50, p95, p99 latency. Network hops cost.

  13. Deploy frequency simulator. Симулируй 10 разработчиков deploy’я в monolith vs в 5 microservices. Conflict rate, rollback rate, deploy time.

  14. Database extraction. Возьми shared DB в monolith. Извлеки одну таблицу в private DB для отдельного сервиса. Покажи migration steps.

  15. Conway’s Law check. Возьми свой проект. Сравни структуру команд и сервисов. Совпадает?


  1. Martin Fowler. “Microservices.” 2014. https://martinfowler.com/articles/microservices.html
  2. Sam Newman. “Building Microservices.” 2nd ed., O’Reilly, 2021.
  3. Sam Newman. “Monolith to Microservices.” O’Reilly, 2019.
  4. Chris Richardson. “Microservices Patterns.” Manning, 2018.
  5. Martin Fowler. “MonolithFirst.” 2015. https://martinfowler.com/bliki/MonolithFirst.html
  6. Martin Fowler. “Strangler Fig Application.” https://martinfowler.com/bliki/StranglerFigApplication.html
  7. Shopify. “Deconstructing the Monolith.” https://shopify.engineering/deconstructing-monolith-designing-software-maximizes-developer-productivity
  8. Monzo. “The Modern Engineering Organization.” https://monzo.com/blog/
  9. DHH. “We’re leaving the cloud.” 2022. https://world.hey.com/dhh/we-re-leaving-the-cloud-654b47e0
  10. Uber Engineering. “Introducing Domain-Oriented Microservice Architecture.” 2020. https://www.uber.com/blog/microservice-architecture/
  11. Conway, M. “How Do Committees Invent?” Datamation, 1968.
  12. Microservices.io patterns. https://microservices.io/patterns/