Ответ
Основной принцип — разделение по бизнес-доменам (Domain-Driven Design, DDD). Каждый микросервис должен отвечать за одну конкретную бизнес-возможность или ограниченный контекст.
Ключевые критерии разделения:
- Высокая связность внутри сервиса — все данные, логика и интерфейсы, относящиеся к одной бизнес-функции, находятся вместе.
- Слабое зацепление между сервисами — сервисы общаются только через четко определенные API (чаще REST/gRPC) или асинхронные события (через брокер вроде Kafka/RabbitMQ). Общая база данных — антипаттерн.
- Автономность развертывания и масштабирования — каждый сервис можно обновить или масштабировать независимо от других.
Пример для e-commerce:
- User Service: управление учетными записями и аутентификацией.
- Catalog Service: управление товарами и категориями.
- Order Service: обработка заказов и корзины.
- Payment Service: взаимодействие с платежными шлюзами.
- Notification Service: отправка email и push-уведомлений.
Практический пример взаимодействия:
// Order Service создает заказ и публикует событие
@PostMapping("/orders")
public Order createOrder(@RequestBody OrderRequest request) {
Order order = orderService.create(request);
// Асинхронное событие для других сервисов
eventPublisher.publish(new OrderCreatedEvent(order.getId(), order.getTotal()));
return order;
}
// Payment Service подписывается на событие и начинает обработку платежа
@EventListener
public void handleOrderCreated(OrderCreatedEvent event) {
paymentService.initiatePayment(event.getOrderId(), event.getAmount());
}
Важно избегать:
- Слишком мелкого разбиения (наносервисы): увеличивает операционную сложность и накладные расходы на межсервисное взаимодействие.
- Разделения по техническим слоям: создание отдельных сервисов для "всех контроллеров", "всех репозиториев" — это распределенная монолитная архитектура.
Оптимальный размер сервиса часто определяют как "размер, которым может владеть одна небольшая команда" (2-8 разработчиков).