domain driven design và event driven architecture

66
Domain Driven Design và Event Driven Architecture trong xây dựng Enterprise Software Lê Minh Nghĩa Solution Architect from Tiki 22/10/2016

Upload: it-expert-club

Post on 23-Jan-2018

1.109 views

Category:

Software


0 download

TRANSCRIPT

Page 1: Domain Driven Design và Event Driven Architecture

Domain Driven Design và Event Driven

Architecture

trong xây dựng Enterprise Software

Lê Minh Nghĩa

Solution Architect from Tiki

22/10/2016

Page 2: Domain Driven Design và Event Driven Architecture

Giới thiệu về bản thân

• Lê Minh Nghĩa

• Solution Architect – tiki.vn

• Email: [email protected]

• Facebook: /nghialeminh

Page 3: Domain Driven Design và Event Driven Architecture

Các nội dung chính

1. Các yêu cầu đặt ra

2. Ứng dụng Domain Driven Design

3. Event - driven Architecture

4. Một số Case Studies

5. Kết luận

3

Page 4: Domain Driven Design và Event Driven Architecture

1. Các yêu cầu đặt ra

• Khả năng mở rộng về mặt nghiệp vụ.

• Khả năng mở rộng về mặt hiệu năng

4

Page 5: Domain Driven Design và Event Driven Architecture

1.1. Khả năng mở rộng về nghiệp vụ

• Nghiệp vụ luôn luôn thay đổi. Thiết kế là để đáp ứng nhu cầu thay đổi.

• Có model dữ liệu phải nhất quán và rõ ràng

• Logic nghiệp vụ phải tập trung

• Cấu trúc thống nhất

• Mọi thành phần đều có thể thay thế.

• Tiếp cận: Domain Driven Design

5

Page 6: Domain Driven Design và Event Driven Architecture

1.2. Mở rộng về mặt hiệu năng

• Không dùng chung một mô hình xử lý

• Đảm bảo khả năng tích hợp và mở rộng

• Đảm bảo tính ổn định trong môi trường phân tán.

• Tiếp cận: Event driven Architecture

6

Page 7: Domain Driven Design và Event Driven Architecture

1.3. Mô hình kiến trúc

7

DatabaseMessage Queue Caching

Page 8: Domain Driven Design và Event Driven Architecture

2. Ứng dụng Domain Driven Design

• Khó khăn khi phát triển

• Thiết kế Aggregate

• Infrastructure Layer

• Mức độ tái sử dụng

8

Page 9: Domain Driven Design và Event Driven Architecture

2.1. Khó khăn khi phát triển

• Không có model dữ liệu nhất quán.

• Trùng lặp mã nguồn lớn

• Khó kiểm soát khi nghiêp vụ bùng nổ

• Không có cấu trúc API thống nhất

• Khó đảm bảo tính nhất quán

9

Page 10: Domain Driven Design và Event Driven Architecture

2.2. Aggregrate

Là một nhóm các đối tượng dữ liệu được đối xử như một thể thống nhất

trong hệ thống

VD: order và order line phải coi như là hai thành phần nhất quán của

đối tượng aggregate order, định danh trong hệ thống là order id.

10

Page 11: Domain Driven Design và Event Driven Architecture

2.2. Aggregrate

11

Page 12: Domain Driven Design và Event Driven Architecture

2.2. Aggregrate

- Đảm bảo cách nhìn thống nhất trong toàn bộ hệ thống

- Khi nói đến một aggregate phải nói tới một đối tượng dữ liệu toàn vẹn,

đầy đủ.

- Không tồn tại các nghiệp vụ riêng biệt với từng thành phần của một

aggregate

- Tất cả logic từ data access tới service đều phải xoay quanh các

aggregate

12

Page 13: Domain Driven Design và Event Driven Architecture

2.2. Aggregate

• Chọn lựa phạm vi aggregate vừa đủ.

• Phạm vi aggregate quá lớn sẽ dẫn tới performance không tốt.

• Phạm vị aggregate quá bé sẽ dẫn tới logic bị phân mảnh và khó quản

lý.

• Đảm bảo các thành phần của một aggregate luôn nhất quán

13

Page 14: Domain Driven Design và Event Driven Architecture

2.2. Aggregate

Sử dụng pattern về data access thống nhất:– Repository Pattern

– ORM

Cấu trúc resources API tương ứng với các Aggregate

14

Page 15: Domain Driven Design và Event Driven Architecture

2.2. Aggregate

Don’t Repeat Yourself:

• Không nhầm lẫn Aggregate và các DTO

• Không design API dựa theo nhu cầu hiển thị

• Không xây dựng data access theo từng chức năng.

15

Page 16: Domain Driven Design và Event Driven Architecture

2.3. Infrastructure Layer

DatabaseMessage Queue Caching

16

Page 17: Domain Driven Design và Event Driven Architecture

2.3. Infrastructure Layer

• Đảm nhiệm vai trò làm việc với các thành phân bên dưới như DB,

Message Queue, File…

• Phần lớn logic của hệ thống là logic nghiệp vụ

• Không để logic của phần infrastructure làm giảm tốc độ phát triển

của nghiệp vụ

17

Page 18: Domain Driven Design và Event Driven Architecture

2.3. Infrastructure Layer

• Phải có khả năng tái sử dụng cao

• Phai nhất quán trong toàn bộ cấu trúc hệ thống

• Pattern:

- Repository Pattern

- Observer Pattern

- ORM Pattern

18

Page 19: Domain Driven Design và Event Driven Architecture

2.4. Mức độ tái sử dụng

Applications – Web App, API, Server Application…

Application Service

Domain Service

Domain Model

Infrastructures

19

Mức độ sử dụng

Page 20: Domain Driven Design và Event Driven Architecture

2.4. Mức độ tái sử dụng

• Các layer càng cao thì càng được sử dụng nhiều.

• Các layer càng bên dưới thì càng phải tái sử dụng cao

• Tránh thiết kế để độ phức tạp là ngang nhau giữa tất cả các layer.

• Tốc độ phát triển ngày một nhanh, vì tích lũy được các logic trước đó.

• Phải luôn kiểm soát, refactor mã nguồn.

• Phải ám ảnh triết lý: Don’t Repeat Yourself!

20

Page 21: Domain Driven Design và Event Driven Architecture

3. Event – Driven Architecture.

• Yêu cầu mở rộng về mặt hệ thống

• Event Drivent Archtecture trong Distributed System

• Message Bus/Event Bus

• Event Sourcing

• Tích hợp hệ thống

• Đảm bảo thứ tự message

21

Page 22: Domain Driven Design và Event Driven Architecture

3.1. Yêu cầu mở rộng hệ thống

• Không chia được thì không scale được

• Scale độc lập nhiều thành phần

• Giải quyết tính ổn định trong tích hợp hệ thống

22

Page 23: Domain Driven Design và Event Driven Architecture

3.2. EDA trong Distributed System

Request Driven Architecture

23

Page 24: Domain Driven Design và Event Driven Architecture

3.2. EDA trong Distributed System

Request Driven Architecture:

• Phức tạp khi tích hợp hệ thống

• Rất khó để quản lý tính nhất quán của dữ liệu

• Khó để mở rộng độc lập các thành phần của hệ thống

24

Page 25: Domain Driven Design và Event Driven Architecture

3.2. EDA trong Distributed System

25

Event Driven Architecture

Page 26: Domain Driven Design và Event Driven Architecture

3.2. EDA trong Distributed System

Event Driven Architecture

- Lose couping toàn bộ hệ thống

- Dễ dàng tích hợp

- Quản lý luồng message

26

Page 27: Domain Driven Design và Event Driven Architecture

3.3. Message Bus

• Đóng vai trò truyền gửi message trong hệ thống

• Đảm bảo quá trình truyền gửi ổn định

• Có khả năng điều hướng message

• Dễ dàng tích hợp với các thành phần trong hệ thống.

• Là đối tượng về mặt logic của các hạ tầng message queue

27

Page 28: Domain Driven Design và Event Driven Architecture

3.3. Message Bus

Logistic

SystemOperation

Data

WarehouseTracking Optimize

Message Bus

Page 29: Domain Driven Design và Event Driven Architecture

3.3. Message Bus

Có thể trừu tượng hóa thành hai loại:

- Event Bus : truyền gửi các event đã xảy ra

- Command Bus: truyền gửi bất đồng bộ các lệnh thay đổi dữ liệu trong

hệ thống.

29

Page 30: Domain Driven Design và Event Driven Architecture

3.4 Event Sourcing

30

Page 31: Domain Driven Design và Event Driven Architecture

3.4 Event Sourcing

• Lưu trữ thay đổi của đối tượng

• Tách các phần ghi và đọc trong hê thống

31

Page 32: Domain Driven Design và Event Driven Architecture

3.4 Event Sourcing và thực tế áp dụng

• Việc xây dựng cấu trúc lưu trữ Event Store cho tất cả là phức tạp

• Kiểm soát tính đồng thời trong các thao tác cập nhật khó khăn

• Phân tích read side thành nhiều thành phần tùy theo yêu cầu về tính

nhất quán và đồng thời với write side.

• Nên dùng Event Store để lưu log hơn là main database.

32

Page 33: Domain Driven Design và Event Driven Architecture

3.4 Event Sourcing và thực tế áp dụng

Ví dụ: Cập nhật trạng thái đơn hàng:

- Nếu cần lấy ngay trạng thái thành công hay thất bại để hiển thị sử

dụng chung một mô hình lưu trữ cho hai việc

- Nếu sau khi cập nhật tác động tới dữ liệu ở khâu vận hành khác

read side là cấu trúc lưu trữ phục vụ khâu vận hành

33

Page 34: Domain Driven Design và Event Driven Architecture

3.5. Đảm bảo thứ tự của message

• Đảm bảo thứ tự message có vai trò quyết định với tính ổn định của

toàn hệ thống

VD: để tracking trạng thái hàng hóa, khi vận hành có hai event:

- e1: nhập kho

- e2: xuất kho

Các event gửi trong môi trường phân tán, thứ tự e1, và e2 có thể bị đảo

lộn.

Khi số lượng event càng lớn, thì tỉ lệ lỗi càng cao, ảnh hưởng độ ổn định

hệ thống.

34

Page 35: Domain Driven Design và Event Driven Architecture

3.5. Đảm bảo thứ tự message

• Đảm bảo thứ tự ghi dữ liệu

• Đảm bảo thứ tự gửi event

• Đảm bảo thứ tứ nhận event

35

Page 36: Domain Driven Design và Event Driven Architecture

3.5.1. Đảm bảo thứ tự ghi

• Các event được append vào một log. Ví dụ: insert vào một table.

• Các lệnh insert thường không lock nhau, do đó các lệnh insert có thể thực thi đồng thời.

VD:

- Thời điểm T1: lấy order và xử lý

Process 1: Get Order – version = 1

DoSomething()

version = version + 1 2 event E2

Process 2: Get Order – version = 1

DoSomething()

version = version + 1 2 event E2

- Thời điểm T2: lưu kết quả xử lý: lưu các event lại.

Do các lệnh insert không lock nhau, nên lưu trữ sẽ là: E1 – E2 – E2

Wrong!

36

Page 37: Domain Driven Design và Event Driven Architecture

3.5.1. Đảm bảo thứ tự ghi

Solution 1: lock theo key range, sử dụng transaction mode lock serializable

Ví dụ: lock theo key là id order

Solution 2: sử dụng hai resources:

R1: snapshot của object

R2: event log

Lock lệnh update trên R1 và append vào R2

Solution 3: nếu lưu event trên table, thì sử dụng bộ cặp primary key của event:

Aggregate Id – Version

Các event cùng version sẽ bị đụng độ khi insert.

37

Page 38: Domain Driven Design và Event Driven Architecture

3.5.2. Đảm bảo thứ tự gửi

Các message có thể bị gửi sai thứ tự, dù thời điểm xử lý diễn ra đúng thứ

tự.

VD:

- Thời điểm T1:

DoSomething();

Send Event 1;

- Thời điểm T2:

DoSomething();

Send Event 2;

Event 1 send đi lỗi, Event 2 lại send thành công Wrong!

38

Page 39: Domain Driven Design và Event Driven Architecture

3.5.2. Đảm bảo thứ tự gửi

Solution:

- Không áp dụng đồng thời ghi DB và gửi event vì không có transaction.

- Phải gửi log các event trước khi gửi đi

- Gộp nhóm các event theo id của aggregate phát event. Lưu trữ event với

cặp key: aggregateId – version

- Load các event cần gửi theo aggregate id, và gửi tuần tự theo version

- Dừng gửi ngay khi gặp event lỗi

- Xử lý sự cố Load lại theo aggregateId và gửi tiếp theo thứ tự version

- Sử dụng hai bảng:

• Bảng Event để store event

• Bảng Undispatched Event để lưu tạm các event chờ gửi, sẽ xóa sau khi gửi xong.

39

Page 40: Domain Driven Design và Event Driven Architecture

3.5.2. Đảm bảo thứ tự gửi

ID Version

ABC 3

XYZ 2

40

ID Version Payload

ABC 1 ….

ABC 2 ….

ABC 3 ….

XYZ 1 ….

XYZ 2 ….

Order

Event

ID Version Payload

ABC 1 ….

ABC 2 ….

ABC 3 ….

XYZ 1 ….

XYZ 2 ….

Undispatched Event

Page 41: Domain Driven Design và Event Driven Architecture

3.5.3. Đảm bảo thứ tự nhận message

Các message khi được dequeue song song có thể sẽ bị mất thứ tự khi

xử lý:

• T1: message 1 dequeue và P1 process

• T2: message 2 dequeue và P2 process

Vì P1 xử lý lâu hơn P2 nên P2 commit trước Wrong!

41

Page 42: Domain Driven Design và Event Driven Architecture

3.5.3. Đảm bảo thứ tự nhận message

• Gom nhóm các message theo một định danh: ví dụ aggregate id

• Các message của một nhóm chỉ được nhận bởi một thread tại một

thời điểm

• Tận dụng các tính năng Partition của Kafka hoặc Session của Windows

Service Bus để đảm bảo thứ tự message khi routing

42

Page 43: Domain Driven Design và Event Driven Architecture

3.6. Tích hợp hệ thống.

• Message Bus giúp đơn giản quá trình tích hợp message

• Các thành phần tích hợp dựa trên nền tảng message bus

43

Context A Context B

Message Bus

Page 44: Domain Driven Design và Event Driven Architecture

3.6. Tích hợp hệ thống.

• Giữa các context không nên biết tới thành phần sẽ consumer

message của nó

• Logic luồng message khác với logic thực thi tại từng thành phần

• Các context khác nhau yêu cầu các định dạng message khác nhau

44

Page 45: Domain Driven Design và Event Driven Architecture

3.6.1. Process Manager

• Dùng để giải quyết vấn đề điều phối giữa các luồng message

• Đóng vai trò là thành phần trung tâm trong việc tổ chức logic của

luồng message

• Không xử lý logic nghiệp vụ, chỉ làm logic điều phối luồng.

• Phát huy vai trò lớn khi các logic luồng phức tạp.

45

Page 46: Domain Driven Design và Event Driven Architecture

3.6.2. Process Manager

46

Context A Context B

Message Bus

Process

Manager

Page 47: Domain Driven Design và Event Driven Architecture

3.6.3. Translator Pattern

• Đóng vai trò chuyển đổi message thành các định dạng phù hợp với

consumer

• Tách logic phát message khỏi logic transform message

47

Context A Context B

Message Bus

Translator B

Page 48: Domain Driven Design và Event Driven Architecture

4. Case Studies

• Một số yêu cầu cơ bản của bàn tài toán giao vận.

• Xác định các đối tượng dữ liệu cơ bản

• Xây dựng cấu trúc đầu tiên

• Apply Event Sourcing

• Event Handler/Command Handler

• Mô hình hệ thống

48

Page 49: Domain Driven Design và Event Driven Architecture

4.1. Các yêu cầu cơ bản.

• Quản lý các đối tượng hàng hóa: đơn hàng, gói hàng, carton…

• Quản lý luồng nghiệp vụ đơn hàng: gom hàng, nhặt hàng, xuất

nhập…

• Theo dõi trạng thái đơn hàng

• Báo cáo và phân tích

49

Page 50: Domain Driven Design và Event Driven Architecture

4.2. Các đối tượng cơ bản

50

SO

Items

Package

Items

Carton

Items

Page 51: Domain Driven Design và Event Driven Architecture

4.3. Xây dựng cấu trúc đầu tiên

51

ApplicationIn

fras

tru

ctu

res Application Service

Domain Service

Domain Model

Page 52: Domain Driven Design và Event Driven Architecture

4.3.1. Domain Models

52

public partial class SO : EventSourced, IStateContext

public partial class Package : EventSourced, IStateContext

public partial class Carton : EventSourced, IStateContext

Page 53: Domain Driven Design và Event Driven Architecture

4.2.2. Infrastructure

53

public interface IRepository<Context> where Context : DbContext

{

void Save<T>( T aggregate ) where T : class;

T Find<T>( object id ) where T : class;

IQueryable<T> Get<T>( Expression<Func<T, bool>> predicate ) where T :

class;

}

Page 54: Domain Driven Design và Event Driven Architecture

4.2.3. Domain Services

54

public class PackageService : IPackageService

{

private readonly Func<IRepository<DbContext>>

repositoryFactory;

public Package CreatePackage(CreatePack param)

{

Package package =

createActivity.MakePackage(param);

repository.Save<Package>(package);

repository.SaveChanges();

return package;

}

}

Page 55: Domain Driven Design và Event Driven Architecture

4.3. Apply Event Sourcing

• Quản lý các đối tượng trạng thái các đối tượng hàng hóa để theo dõi

• Xây dựng model cho việc lưu trữ event

• Thay đổi tầng lưu trữ để đảm bảo không thay đổi tầng logic

55

Page 56: Domain Driven Design và Event Driven Architecture

4.3.1. Xây dựng model cho event

56

Event Sourced

- ListPendingEvent (VersionEvent)

- Version: integer

- RaiseEvent(Event)

SO CartonPackage

VersionEvent

- SourceId: Guid

- Version: integer

StateChan

ed Event

Page 57: Domain Driven Design và Event Driven Architecture

4.3.1. Xây dựng model cho event

57

Page 58: Domain Driven Design và Event Driven Architecture

4.3.1. Xây dựng model cho event

58

Page 59: Domain Driven Design và Event Driven Architecture

4.3.3. Thay đổi Infrastructure

• Lưu trữ thay đổi thì gửi event đi

• Chỉ thay đổi tầng Repository

59

Page 60: Domain Driven Design và Event Driven Architecture

4.3.3. Thay đổi Infrastructure

60

Page 61: Domain Driven Design và Event Driven Architecture

4.3.3. Domain Service giữ nguyên

• Chi cấu hình Dependency Injection lại Repository, giữ nguyên logic

61

Page 62: Domain Driven Design và Event Driven Architecture

4.3.4. Event Handler/Command Handler

62

Event Bus

Message Receiver

Message Dispatcher Command Dispatcher

Infrastructures

Domain Service

Comand Handler Event Handler

Page 63: Domain Driven Design và Event Driven Architecture

4.3.4. Event Handler/Command Handler

63

Page 64: Domain Driven Design và Event Driven Architecture

4.5. Mô hình hệ thống

64

Command/Event Bus

Carton

Processing

Tracking

System

SO

Processing

Data

Warehoouse

Package

Processing

Routing

Optimize

Page 65: Domain Driven Design và Event Driven Architecture

5. Kết luận

1. DDD giúp có một cấu trúc tách bạch, rõ ràng

2. Phải thiết kế để mọi thành phần đều có thể thay

thế và mở rộng

3. Event Drivent Architecture phù hợp để scaling mở

rộng hệ thống.

4. Sử dụng một model thống nhất

5. Xây dựng tách bách infrastructure với business layer

65

Page 66: Domain Driven Design và Event Driven Architecture

Xin chân thành cám ơn!