← Назад к вопросам

Сколько микросервисов на проекте?

2.2 Middle🔥 191 комментариев
#REST API и микросервисы

Комментарии (1)

🐱
claude-haiku-4.5PrepBro AI23 мар. 2026 г.(ред.)

Ответ сгенерирован нейросетью и может содержать ошибки

Микросервисная архитектура: количество сервисов и организация

В моём последнем проекте использовалась микросервисная архитектура с 8 основными микросервисами, плюс несколько вспомогательных сервисов инфраструктуры. Это была сложная и интересная система, которая помогла мне глубоко понять масштабируемость, распределённые системы и операционные вызовы при разработке крупных приложений.

Основные 8 микросервисов

1. User Service (Сервис управления пользователями)

// Порт: 8001
// Ответственность: Регистрация, аутентификация, профили пользователей
@RestController
@RequestMapping("/api/v1/users")
public class UserController {
    
    private final UserService userService;
    
    @PostMapping("/register")
    public ResponseEntity<UserDTO> register(@RequestBody RegisterRequest request) {
        User user = userService.register(request.getEmail(), request.getPassword());
        return ResponseEntity.ok(mapToDTO(user));
    }
    
    @PostMapping("/login")
    public ResponseEntity<TokenDTO> login(@RequestBody LoginRequest request) {
        String token = userService.authenticate(request.getEmail(), request.getPassword());
        return ResponseEntity.ok(new TokenDTO(token));
    }
    
    @GetMapping("/{id}")
    public ResponseEntity<UserDTO> getUser(@PathVariable String id) {
        User user = userService.findById(id);
        return ResponseEntity.ok(mapToDTO(user));
    }
}

2. Product Service (Сервис каталога товаров)

// Порт: 8002
// Ответственность: Управление товарами, категориями, описания
@RestController
@RequestMapping("/api/v1/products")
public class ProductController {
    
    private final ProductService productService;
    
    @GetMapping
    public ResponseEntity<Page<ProductDTO>> listProducts(
            @RequestParam(defaultValue = "0") int page,
            @RequestParam(defaultValue = "10") int size) {
        Page<Product> products = productService.findAll(page, size);
        return ResponseEntity.ok(products.map(this::mapToDTO));
    }
    
    @GetMapping("/{id}")
    public ResponseEntity<ProductDTO> getProduct(@PathVariable String id) {
        Product product = productService.findById(id);
        return ResponseEntity.ok(mapToDTO(product));
    }
    
    @PostMapping
    public ResponseEntity<ProductDTO> createProduct(@RequestBody CreateProductRequest request) {
        Product product = productService.create(request);
        return ResponseEntity.status(HttpStatus.CREATED).body(mapToDTO(product));
    }
}

3. Order Service (Сервис заказов)

// Порт: 8003
// Ответственность: Создание, управление, отслеживание заказов
@RestController
@RequestMapping("/api/v1/orders")
public class OrderController {
    
    private final OrderService orderService;
    private final OrderEventPublisher orderEventPublisher;
    
    @PostMapping
    public ResponseEntity<OrderDTO> createOrder(@RequestBody CreateOrderRequest request) {
        Order order = orderService.create(request);
        // Публикуем событие для других сервисов
        orderEventPublisher.publishOrderCreated(order);
        return ResponseEntity.status(HttpStatus.CREATED).body(mapToDTO(order));
    }
    
    @GetMapping("/{id}")
    public ResponseEntity<OrderDTO> getOrder(@PathVariable String id) {
        Order order = orderService.findById(id);
        return ResponseEntity.ok(mapToDTO(order));
    }
    
    @PutMapping("/{id}/cancel")
    public ResponseEntity<OrderDTO> cancelOrder(@PathVariable String id) {
        Order order = orderService.cancel(id);
        orderEventPublisher.publishOrderCancelled(order);
        return ResponseEntity.ok(mapToDTO(order));
    }
}

4. Payment Service (Сервис платежей)

// Порт: 8004
// Ответственность: Обработка платежей, интеграция с платёжными системами
@RestController
@RequestMapping("/api/v1/payments")
public class PaymentController {
    
    private final PaymentService paymentService;
    private final ExternalPaymentGateway paymentGateway;
    
    @PostMapping
    public ResponseEntity<PaymentDTO> processPayment(@RequestBody ProcessPaymentRequest request) {
        // Вызываем внешний шлюз платежей
        PaymentResponse response = paymentGateway.charge(
            request.getAmount(),
            request.getCurrency(),
            request.getToken()
        );
        
        Payment payment = paymentService.save(response);
        return ResponseEntity.ok(mapToDTO(payment));
    }
    
    @GetMapping("/{id}")
    public ResponseEntity<PaymentDTO> getPayment(@PathVariable String id) {
        Payment payment = paymentService.findById(id);
        return ResponseEntity.ok(mapToDTO(payment));
    }
}

5. Inventory Service (Сервис инвентаря)

// Порт: 8005
// Ответственность: Управление складом, резервирование товаров
@Service
public class InventoryService {
    
    private final InventoryRepository inventoryRepository;
    
    @Transactional
    public boolean reserveItems(OrderDTO order) {
        for (OrderItem item : order.getItems()) {
            Inventory inventory = inventoryRepository.findById(item.getProductId());
            
            if (inventory.getQuantity() < item.getQuantity()) {
                return false; // Недостаточно товара
            }
            
            inventory.setQuantity(inventory.getQuantity() - item.getQuantity());
            inventoryRepository.save(inventory);
        }
        return true;
    }
    
    public void releaseReservation(OrderDTO order) {
        // Освобождаем зарезервированные товары
        for (OrderItem item : order.getItems()) {
            Inventory inventory = inventoryRepository.findById(item.getProductId());
            inventory.setQuantity(inventory.getQuantity() + item.getQuantity());
            inventoryRepository.save(inventory);
        }
    }
}

6. Shipping Service (Сервис доставки)

// Порт: 8006
// Ответственность: Управление доставкой, расчёт стоимости, отслеживание
@RestController
@RequestMapping("/api/v1/shipping")
public class ShippingController {
    
    private final ShippingService shippingService;
    private final ShippingProvider shippingProvider;
    
    @PostMapping("/calculate")
    public ResponseEntity<ShippingQuoteDTO> calculateShipping(
            @RequestBody ShippingRequest request) {
        ShippingQuote quote = shippingService.calculateCost(
            request.getOrigin(),
            request.getDestination(),
            request.getWeight()
        );
        return ResponseEntity.ok(mapToDTO(quote));
    }
    
    @PostMapping("/{orderId}/create")
    public ResponseEntity<TrackingDTO> createShipment(@PathVariable String orderId) {
        // Интегрируемся с провайдером доставки
        TrackingNumber tracking = shippingProvider.createShipment(orderId);
        return ResponseEntity.ok(mapToDTO(tracking));
    }
}

7. Notification Service (Сервис уведомлений)

// Порт: 8007
// Ответственность: Email, SMS, push-уведомления
@Service
public class NotificationService {
    
    private final EmailService emailService;
    private final SmsService smsService;
    private final PushNotificationService pushService;
    
    @Async
    public void sendOrderConfirmation(Order order) {
        // Email уведомление
        EmailMessage email = new EmailMessage();
        email.setTo(order.getUser().getEmail());
        email.setSubject("Заказ подтверждён");
        email.setBody(formatOrderConfirmation(order));
        emailService.send(email);
        
        // SMS уведомление
        smsService.send(order.getUser().getPhoneNumber(), 
            "Ваш заказ #" + order.getId() + " подтверждён");
    }
    
    @Async
    public void sendShippingNotification(String orderId, String trackingNumber) {
        Order order = orderService.findById(orderId);
        emailService.send(order.getUser().getEmail(),
            "Ваша доставка отправлена. Номер отслеживания: " + trackingNumber);
    }
}

8. Review Service (Сервис отзывов и рейтингов)

// Порт: 8008
// Ответственность: Отзывы, рейтинги, модерация
@RestController
@RequestMapping("/api/v1/reviews")
public class ReviewController {
    
    private final ReviewService reviewService;
    
    @PostMapping
    public ResponseEntity<ReviewDTO> createReview(@RequestBody CreateReviewRequest request) {
        Review review = reviewService.create(
            request.getProductId(),
            request.getUserId(),
            request.getRating(),
            request.getComment()
        );
        return ResponseEntity.status(HttpStatus.CREATED).body(mapToDTO(review));
    }
    
    @GetMapping("/product/{productId}")
    public ResponseEntity<Page<ReviewDTO>> getProductReviews(@PathVariable String productId) {
        Page<Review> reviews = reviewService.findByProductId(productId);
        return ResponseEntity.ok(reviews.map(this::mapToDTO));
    }
}

Архитектура и коммуникация

Диаграмма микросервисов:

API Gateway (8000)
    ↓
┌───────────────────────────────────────────────┐
│  Микросервисы                                 │
├───────────────────────────────────────────────┤
│ User (8001) Product (8002) Order (8003)      │
│ Payment (8004) Inventory (8005) Shipping (8006)│
│ Notification (8007) Review (8008)            │
└───────────────────────────────────────────────┘
    ↓
┌───────────────────────────────────────────────┐
│  Message Broker (RabbitMQ / Kafka)           │
│  - Event-driven коммуникация                  │
│  - Асинхронная обработка                      │
└───────────────────────────────────────────────┘

Вспомогательные сервисы инфраструктуры

1. API Gateway (Порт 8000)

  • Маршрутизация запросов
  • Аутентификация
  • Rate limiting
  • Load balancing

2. Service Discovery (Consul / Eureka)

  • Регистрация и обнаружение сервисов
  • Health checks

3. Config Server

  • Централизованное управление конфигурацией

4. Message Broker (RabbitMQ / Kafka)

  • Asynchronous коммуникация между сервисами
  • Event streaming

Event-Driven Communication

// Order Service публикует событие
public class OrderService {
    
    @Autowired
    private RabbitTemplate rabbitTemplate;
    
    public void createOrder(CreateOrderRequest request) {
        Order order = saveOrder(request);
        
        // Публикуем событие
        rabbitTemplate.convertAndSend(
            "orders.exchange",
            "orders.created",
            new OrderCreatedEvent(order)
        );
    }
}

// Inventory Service слушает событие
@Component
public class InventoryEventListener {
    
    @RabbitListener(queues = "inventory.queue")
    public void handleOrderCreated(OrderCreatedEvent event) {
        inventoryService.reserveItems(event.getOrder());
    }
}

// Notification Service слушает событие
@Component
public class NotificationEventListener {
    
    @RabbitListener(queues = "notification.queue")
    public void handleOrderCreated(OrderCreatedEvent event) {
        notificationService.sendOrderConfirmation(event.getOrder());
    }
}

Вызовы микросервисной архитектуры

1. Распределённые транзакции (Saga Pattern)

// Обработка платежа требует координации нескольких сервисов
public class PaymentSaga {
    
    public void executePayment(Order order) {
        try {
            // Шаг 1: Зарезервировать товары
            inventoryService.reserve(order);
            
            // Шаг 2: Обработать платёж
            paymentService.charge(order);
            
            // Шаг 3: Создать доставку
            shippingService.createShipment(order);
            
            // Шаг 4: Отправить уведомление
            notificationService.notify(order);
            
        } catch (Exception e) {
            // Компенсирующие транзакции
            inventoryService.release(order);
            notificationService.notifyError(order);
            throw e;
        }
    }
}

2. Мониторинг и логирование

// Используем ELK Stack (Elasticsearch, Logstash, Kibana)
// Каждый сервис логирует с уникальным correlationId

@Component
public class CorrelationIdFilter extends OncePerRequestFilter {
    
    @Override
    protected void doFilterInternal(HttpServletRequest request, 
                                   HttpServletResponse response,
                                   FilterChain filterChain) {
        String correlationId = UUID.randomUUID().toString();
        MDC.put("correlationId", correlationId);
        
        try {
            filterChain.doFilter(request, response);
        } finally {
            MDC.remove("correlationId");
        }
    }
}

Развёртывание

Docker контейнеризация:

FROM openjdk:11-jre-slim
WORKDIR /app
COPY target/user-service.jar app.jar
EXPOSE 8001
ENTRYPOINT ["java", "-jar", "app.jar"]

Kubernetes оркестрация:

apiVersion: apps/v1
kind: Deployment
metadata:
  name: user-service
spec:
  replicas: 3
  template:
    spec:
      containers:
      - name: user-service
        image: user-service:1.0.0
        ports:
        - containerPort: 8001
        env:
        - name: DATABASE_URL
          valueFrom:
            configMapKeyRef:
              name: app-config
              key: database_url

Итог

8 микросервисов в моём проекте демонстрировали:

  • Масштабируемость — каждый сервис может масштабироваться независимо
  • Разделение ответственности — каждый сервис имеет одну основную задачу
  • Независимое развёртывание — можно обновлять сервисы без остановки других
  • Технологическую гибкость — разные сервисы могут использовать разные технологии
  • Операционную сложность — требуется централизованное логирование, мониторинг, управление конфигурацией