Files
sa-lessons/modules/module2/sections/04-data-management.md
Alexander Abakumov 15e744da49 Initial commit: Complete Software Architecture course with 11 modules
- Added comprehensive course structure with 11 modules
- Included theoretical content, practical examples, and tasks
- Multi-language code examples (Java, Rust, Node.js, Python)
- Detailed analysis of architectural approaches and trade-offs
- Complete caching strategies documentation
- Architecture examples from real-world systems (Twitter, Netflix, Uber)
- Structured navigation and learning path
- Ready for educational use
2025-09-09 22:08:07 +03:00

6.0 KiB
Raw Blame History

Управление данными в микросервисах

Навигация


База данных на сервис

Принцип: Каждый микросервис имеет собственную базу данных.

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

  • Независимость данных
  • Разные типы БД для разных задач
  • Независимое масштабирование

Недостатки:

  • Сложность транзакций
  • Проблемы с консистентностью
  • Дублирование данных

Паттерны управления данными

1. Saga Pattern

Определение: Паттерн для управления распределенными транзакциями.

Choreography Saga

// Order Service
public class OrderService {
    public void createOrder(CreateOrderRequest request) {
        Order order = new Order(request);
        orderRepository.save(order);
        
        // публикуем событие
        eventPublisher.publish(new OrderCreatedEvent(order.getId(), request.getItems()));
    }
}

// Inventory Service
@EventHandler
public class InventoryEventHandler {
    public void handleOrderCreated(OrderCreatedEvent event) {
        try {
            inventoryService.reserveItems(event.getItems());
            eventPublisher.publish(new ItemsReservedEvent(event.getOrderId()));
        } catch (InsufficientStockException e) {
            eventPublisher.publish(new OrderCancelledEvent(event.getOrderId()));
        }
    }
}

// Payment Service
@EventHandler
public class PaymentEventHandler {
    public void handleItemsReserved(ItemsReservedEvent event) {
        try {
            paymentService.processPayment(event.getOrderId());
            eventPublisher.publish(new PaymentProcessedEvent(event.getOrderId()));
        } catch (PaymentFailedException e) {
            eventPublisher.publish(new OrderCancelledEvent(event.getOrderId()));
        }
    }
}

Orchestration Saga

@Service
public class OrderOrchestrator {
    public void processOrder(CreateOrderRequest request) {
        Order order = orderService.createOrder(request);
        
        try {
            // шаг 1: резервирование товаров
            inventoryService.reserveItems(order.getId(), request.getItems());
            
            // шаг 2: обработка платежа
            paymentService.processPayment(order.getId(), request.getPayment());
            
            // шаг 3: подтверждение заказа
            orderService.confirmOrder(order.getId());
            
        } catch (Exception e) {
            // компенсирующие транзакции
            compensateOrder(order.getId());
        }
    }
    
    private void compensateOrder(OrderId orderId) {
        try {
            inventoryService.releaseItems(orderId);
            paymentService.refundPayment(orderId);
            orderService.cancelOrder(orderId);
        } catch (Exception e) {
            // логирование ошибок компенсации
        }
    }
}

2. CQRS (Command Query Responsibility Segregation)

Определение: Разделение команд и запросов.

// Command Side
@Service
public class OrderCommandService {
    public void createOrder(CreateOrderCommand command) {
        Order order = new Order(command);
        orderRepository.save(order);
        
        // обновляем read model
        orderReadModelService.updateReadModel(order);
    }
}

// Query Side
@Service
public class OrderQueryService {
    public OrderView getOrderView(OrderId orderId) {
        return orderReadModelRepository.findById(orderId);
    }
    
    public List<OrderView> getOrdersByCustomer(CustomerId customerId) {
        return orderReadModelRepository.findByCustomerId(customerId);
    }
}

3. Event Sourcing

Определение: Хранение событий вместо состояния.

@Entity
public class OrderEvent {
    private Long id;
    private String aggregateId;
    private String eventType;
    private String eventData;
    private LocalDateTime occurredAt;
}

@Service
public class OrderEventStore {
    public void saveEvent(OrderEvent event) {
        eventRepository.save(event);
    }
    
    public List<OrderEvent> getEvents(String aggregateId) {
        return eventRepository.findByAggregateIdOrderByOccurredAt(aggregateId);
    }
}

@Service
public class OrderProjectionService {
    public OrderView buildOrderView(String orderId) {
        List<OrderEvent> events = eventStore.getEvents(orderId);
        OrderView view = new OrderView();
        
        for (OrderEvent event : events) {
            applyEvent(view, event);
        }
        
        return view;
    }
}

Консистентность данных

Типы консистентности:

1. Strong Consistency

  • Все узлы видят одинаковые данные
  • Сложно в распределенных системах
  • Высокая задержка

2. Eventual Consistency

  • Данные в итоге станут консистентными
  • Подходит для большинства случаев
  • Низкая задержка

3. Weak Consistency

  • Нет гарантий консистентности
  • Используется редко

Паттерны для консистентности:

1. Two-Phase Commit (2PC)

Проблема: Блокирующий протокол Решение: Использовать Saga вместо 2PC

2. Three-Phase Commit (3PC)

Улучшение: Меньше блокировок Проблема: Все еще сложный

3. Consensus Algorithms

  • Raft — выбор лидера
  • Paxos — консенсус в распределенных системах