JavaRush /Курси /Модуль 5. Spring /Лекція 206: Практика: проєктування подійно-орієнтованої а...

Лекція 206: Практика: проєктування подійно-орієнтованої архітектури

Модуль 5. Spring
Рівень 13 , Лекція 5
Відкрита

У попередніх лекціях ми познайомилися з Event-Driven Architecture (EDA) — подійно-орієнтованою архітектурою, її принципами та компонентами. Ми розібрали, як події створюють слабке звʼязування між мікросервісами, знижують залежність і покращують масштабованість. Ви дізналися, як працюють асинхронні комунікації, вивчили концепції producers і subscribers, а також зрозуміли, як message brokers, такі як Kafka, RabbitMQ і ActiveMQ, керують передачею даних. Також ми обговорили типові помилки при впровадженні EDA і кращі практики її проєктування.

Настав час застосувати теорію на практиці і спробувати спроєктувати подійно-орієнтовану архітектуру для конкретного кейсу.


Практичне проєктування подійно-орієнтованої архітектури

Постановка задачі: кейс "Магазин електронної комерції"

Уявіть, що вам потрібно розробити архітектуру подій для інтернет-магазину. Як головний архітектор системи, ви стикаєтеся з такими задачами:

  • Опрацювання замовлень, включно з повідомленнями про статус замовлень, оплатою та доставкою.
  • Автоматичне оновлення інформації про наявність товарів на складі.
  • Відправка повідомлень користувачам про знижки на їх улюблені товари.
  • Логування всіх подій для аналітики (наприклад, для побудови звітів).

Наша ціль — використати подійно-орієнтований підхід, щоб знизити звʼязаність сервісів і підвищити відмовостійкість.


Крок 1: Визначення подій

Перший крок — зрозуміти, які події відбуваються в системі. Подія — це така "новина" про те, що щось сталося. Наприклад:

Подія Опис
OrderPlaced Замовлення створене користувачем
OrderPaid Користувач оплатив замовлення
OrderShipped Замовлення відправлено службою доставки
InventoryUpdated Змінилася кількість товару на складі
DiscountCreated Створено нову знижку, яка може зацікавити користувачів
UserNotificationSent Повідомлення відправлено користувачу

Кожна подія має свій payload і метадані, такі як час створення, ідентифікатор користувача тощо.

Крок 2: Ідентифікація producers і subscribers

Тепер, коли ми визначили події, потрібно зрозуміти, хто їх продукує (publishers) і хто на них реагує (subscribers).

Подія Видавець Підписники
OrderPlaced Order Service Inventory Service, Payment Service
OrderPaid Payment Service Shipping Service, Notification Service
OrderShipped Shipping Service Notification Service
InventoryUpdated Inventory Service Analytics Service, Notification Service
DiscountCreated Admin Service Notification Service
UserNotificationSent Notification Service Analytics Service

Приклад:

  • Коли користувач створює замовлення, Order Service публікує подію OrderPlaced. Цю подію обробляє Inventory Service, щоб зменшити кількість товарів на складі, і Payment Service, щоб ініціювати процес оплати.

Крок 3: Створення схеми взаємодії

Давайте візуалізуємо, як сервіси обмінюються подіями. Ось схема, що показує взаємодію через message broker (наприклад, Apache Kafka):

User
  ↓
Order Service ──> OrderPlaced ─┬──> Inventory Service (зменшити склад)
                               └──> Payment Service (ініціювати оплату)
                                    ↓
                                    Payment Service ──> OrderPaid ─┬──> Shipping Service (відправити замовлення)
                                                                   └──> Notification Service (повідомити користувача)
                                    ↓
Shipping Service ──> OrderShipped → Notification Service

Крок 4: Визначення структури подій

Події мають містити корисну інформацію для підписників.

Приклад структури події OrderPlaced:

{
  "eventId": "12345",
  "eventType": "OrderPlaced",
  "timestamp": "2023-10-01T12:34:56Z",
  "payload": {
    "orderId": "7890",
    "userId": "456",
    "orderItems": [
      {
        "productId": "101",
        "quantity": 2
      },
      {
        "productId": "202",
        "quantity": 1
      }
    ],
    "totalPrice": 159.99
  }
}

Подібні структури допомагають уніфікувати обробку подій, бо підписники завжди знають, чого очікувати.

Крок 5: Моделювання message broker

Для реалізації архітектури ми будемо використовувати Apache Kafka. Кожна подія публікуватиметься у свій topic.

Топік Тип події Приклади повідомлень
orders OrderPlaced Дані про створені замовлення
payments OrderPaid Дані про успішні оплати
shipping OrderShipped Дані про відправлені замовлення
inventory InventoryUpdated Дані про зміну залишків на складі
notifications UserNotificationSent Дані про відправлені повідомлення

Вправа: реалізація producer і consumer для події OrderPlaced

Реалізація producer:

// Producer для відправки події OrderPlaced у Kafka
@Component
public class OrderEventProducer {

    private final KafkaTemplate<String, String> kafkaTemplate;

    public OrderEventProducer(KafkaTemplate<String, String> kafkaTemplate) {
        this.kafkaTemplate = kafkaTemplate;
    }

    public void sendOrderPlacedEvent(String orderId, String eventPayload) {
        kafkaTemplate.send("orders", orderId, eventPayload);
        System.out.println("Подія OrderPlaced відправлена: " + eventPayload);
    }
}

Реалізація підписника:

// Consumer для обробки події OrderPlaced
@Component
@KafkaListener(topics = "orders", groupId = "inventory-service")
public class OrderEventConsumer {

    @Autowired
    private InventoryService inventoryService;

    @KafkaHandler
    public void handleOrderPlacedEvent(String message) {
        System.out.println("Отримано подію OrderPlaced: " + message);
        inventoryService.updateInventory(message);
    }
}

Поради з проєктування подійно-орієнтованої архітектури

  • Мінімізуйте залежності. Кожен сервіс має бути максимально ізольований. Наприклад, Notification Service не має знати внутрішню логіку Order Service.
  • Логируйте події. Це допоможе відстежити, що відбувається в системі, особливо в асинхронній обробці.
  • Ідентифікуйте схеми подій. Використовуйте JSON Schema, щоб всі події дотримувалися чіткого формату.
  • Забезпечте узгодженість. Якщо подію не оброблено, її можна повторити завдяки механізму Kafka's "At least once".

Підсумкова вправа

Для закріплення знань спроєктуйте подійно-орієнтовану архітектуру для системи бронювання авіаквитків. Визначте ключові події (FlightBooked, PaymentProcessed, TicketIssued), їх видавців і підписників. Опишіть взаємодію сервісів і створіть схему подій.

Ось і все! Тепер ви практично опанували основи проєктування подійно-орієнтованої архітектури. Попереду — ще більше EDA і асинхронної магії.

Коментарі
ЩОБ ПОДИВИТИСЯ ВСІ КОМЕНТАРІ АБО ЗАЛИШИТИ КОМЕНТАР,
ПЕРЕЙДІТЬ В ПОВНУ ВЕРСІЮ