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 là student-service và other-service:

  • Student service 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 cần được inform cho Other Service để xử lý thêm một số logic khác. 

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é! Thông tin sinh viên mới thêm sẽ được capture bởi Debezium và được publish tới Other service thông qua Apache Kafka.

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

Để làm ví dụ, mình sẽ tạo mới một Maven multiple project với 2 project là student-service và other-service, như sau:

Student Service

Student Service là một Spring Boot application sử dụng Web Starter, Data JPA Starter, PostgreSQL driver, Lombok và Docker Compose Support.

Cho 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. PostgreSQL database này sẽ enable sẵn các cấu hình liên quan đến change data capture, các bạn nhé! Nội dung của tập tin Docker Compose lúc này như sau:

Tập tin compose.yaml này sẽ nằm ở thư mục root của project nha các bạn.

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.

Nội dung của class AddNewStudentRequest và AddNewStudentResponse như sau:

Other Service

Cho Other Service, mình cũng tạo một Spring Boot project sử dụng Spring Boot Starter Kafka.

Other Service sẽ subscribe vào một topic của Apache Kafka, cái topic mà Debezium sẽ public data change của Student Service, đó các bạn! Sau đó thì sẽ in dữ liệu nhận được ra console. Mình sẽ viết code đơn giản như sau:

outboxpattern.public.outbox sẽ là tên của topic mà Debezium publish message data change nhé các bạn.

Tập tin application.yaml của service này, có nội dung như sau:

Mình sẽ định nghĩa một service để chạy Apache Kafka trong tập tin Docker Compose ở trên như sau:

Debezium Server

Cho Debezium Server, mình sẽ định nghĩa một service mới trong tập Docker Compose ở trên, để chạy nó, như sau:

Tập tin cấu hình của Debezium trong thư mục src/main/resource/conf của root project sẽ có nội dung như sau:

Với cấu hình trên, một topic có tên là outboxpattern.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é!

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 Student Service http://localhost:8081/students với phương thức POST, các bạn sẽ thấy kết quả như sau:

Console log của Other Service, các bạn sẽ thấy một message được nhận, như sau:

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

và:

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

Các bạn có thể xem thêm video ở đây:

Add Comment