Outbox Pattern với Debezium – Phần 2

Để làm ví dụ về việc hiện thực Outbox Pattern với Debezium, mình sẽ có một hệ thống với 2 service 1 và 2.

  • Service 1 sẽ expose một API để thêm mới thông tin sinh viên vào database.
  • Thông tin sinh viên mới được thêm này sẽ được capture bởi Debezium và được publish tới Service 2 thông qua Apache Kafka.

Chúng ta sẽ sử dụng Outbox Pattern để đảm bảo tính nhất quán của dữ liệu các bạn nhé!

High level architecture của hệ thống mình sẽ như sau:

Service 1

Service 1 là một Spring Boot application sử dụng Web Starter, Data JPA Starter, PostgreSQL driver, Lombok và Docker Compose Support như sau:

PostgreSQL database server, mình sẽ sử dụng tính năng của Spring Boot hỗ trợ cho Docker Compose để có thể chạy một PostgreSQL database khi chạy ứng dụng lên. Nội dung của tập tin Docker Compose như sau:

Trong tập tin db.sql ở thư mục src/main/resources, table student sẽ được mình định nghĩa như sau:

Entity của class Student và class Repository của nó, có nội dung như sau:

và:

Cũng trong tập tin db.sql này, mình cũng định nghĩa nội dung của outbox table như sau:

  • Cột id dùng làm unique id cho mỗi message sẽ được gửi tới Apache Kafka.
  • aggregate_id là id của domain object liên quan đến event. Trong ví dụ của mình thì là id của sinh viên đó các bạn.
  • type là domain object model liên quan đến event, cho ví dụ của mình là student đó các bạn.
  • event_type là loại event liên quan đến domain object model. Type có thể là thêm mới, update, xoá, …
  • payload là nội dung dưới dạng JSON của event.

Mình cũng thêm entity và class Repository cho outbox table này như sau:

và:

StudentController sẽ expose API thêm mới sinh viên có nội dung như sau:

Cùng với việc insert mới một record vào table student, chúng ta cũng sẽ insert 1 record vào outbox table. Table outbox này sẽ được monitor bởi Debezium để mỗi khi có record mới, Debezium sẽ pick up và gửi một message tới Apache Kafka.

Apache Kafka

 

Debezium

Tập tin cấu hình của Debezium cho ví dụ này của mình sẽ có nội dung như sau:

Với cấu hình trên, một topic có tên là outbox_pattern.public.outbox sẽ được tạo trong Apache Kafka đó các bạn! Tất cả những thay đổi của table outbox sẽ được capture và public lên topic này.

Các bạn xem thêm bài viết Change Data Capture với Debezium để hiểu rõ hơn về những thông tin cấu hình này nhé!

Service 2

Cho Service 2, mình cũng tạo một Spring Boot project sử dụng Spring for Apache Kafka để subscribe vào topic của Apache Kafka, cái topic mà Debezium sẽ public data change của Service 1. Sau đó thì sẽ in dữ liệu nhận được ra console.

Service 2 của mình như sau:

Tập tin application.yaml có nội dung như sau:

Class listen topic outbox_pattern.public.outbox mình sẽ viết code đơn giản như sau:

Bây giờ, nếu chạy tất cả các ứng dụng của hệ thống, sau đó thì request tới Service 1 http://localhost:8081/students?name=Khanh với phương thức POST, các bạn sẽ thấy kết quả như sau:

Table student và table outbox, các bạn cũng sẽ thấy một record mới như sau:

và:

Một message mới cũng được public tới topic outbox_pattern.public.outbox với nội dung như sau:

Như vậy là chúng ta đã hiện thực thành công Outbox Pattern rồi đó các bạn!

Add Comment