kiến thức [Event Tặng Title] Microservice Pattern

Doge Coin

To The Moon
Microservice Pattern

1. Định nghĩa

Có rất nhiều định nghĩa về microservices. Nhưng chúng ta có thể hiểu đơn giản "microservices là các module/service có thể triển khai (deployable) một cách độc lập, được mô hình hóa dựa trên domain business."
Một module/service như thế, được đóng gói về mặt tính năng và có thể giao tiếp với các module/service khác qua network.

Lấy một ví dụ đơn giản: Một website bán hàng, với các chức năng: Đăng ký người dùng, thanh toán, tìm kiếm sản phẩm v.v...
Các module này có thể được implement một cách độc lập với nhau hoặc phụ thuộc nhau. Ví dụ module tìm kiếm sản phẩm hoàn toàn có thể độc lập với module đăng ký người dùng hoặc thanh toán.

Việc này có thể giúp tăng tốc độ triển khai, giảm số lượng test do các module được phát triển độc lập.
Có thể nói "Independent Deployability" là một trong các core concept của Microservices. Phát triển, thay đổi, cập nhật một cách độc lập mà ko quá phụ thuộc vào các service khác.
Để đảm bảo dc tính chất này, cần đảm bảo các service có tính chất "loosely coupled": Thay đổi một service mà không phải thay đổi bất kỳ service nào khác. Điều này cần một quá trình định nghĩa rõ ràng giữa các service, stable contract với nhau. Đôi khi sẽ trở nên khó khăn nếu lựa chọn "sharing database".

Ngoài ra còn 1 số tính chất khác mình sẽ bổ sung sau vì nó "theory" quá.

Phần tiếp theo này mình sẽ dành thời gian để nói về Timeout Antipattern!

2. Timeout Antipattern

Như ở trên đã nói là các module được deploy một cách độc lập, nên một trong những thử thách trong các kiến trúc phân tán đó chính là làm sao để quản lý được khả năng availability cũng như responsiveness.

- Availablity tức là khả năng mà service consumer kết nối và sử dụng service.
- Responsiveness là thời gian cần để trả lời (respond) một request.

Nếu service consumer không thể kết nối tới service, lúc này service consumer sẽ được notified, và có thể chọn các giải pháp như pass error này tới client, hay retry một vài lần nữa.
Giả sử serivce đã được kết nối với nhau, và thực hiện request nhưng vì 1 lý do gì đó service không đưa ra respond. Trong trường hợp này, service consumer có thể chọn chờ mãi mãi hoặc đặt ra 1 giá trị timeout!

Sử dụng timeout là một cách nhưng nó sẽ dẫn tới timeout anti-pattern!
Câu hỏi là, đặt timeout có phải là tốt hay ko?

Nếu timeout quá nhỏ, một request sắp thành công và "bùm", timeout error happen! Và lúc này bạn phải thực hiện lại request đấy.
Nếu timeouut quá lớn, vậy sẽ phải chờ rất lâu để xác định một request thật sự xảy ra lỗi.

- Có một số cách để ước lượng con số timeout này. Ví dụ dựa vào database timeout, hoặc tính toán khoảng thời gian tối đa xử lý và nhân 2, 3 nó lên như là một extra buffer. Giả sử một request mất tối đa 5 giây, vậy timeout sẽ là 10 giây. Nghĩa là mỗi request từ service consumer cần chờ 10 giây để xác định service not responsive. Nhưng là user thường sẽ chỉ có thể chờ 2-3 giây trước khi hủy thao tác. Do đó cần 1 cơ chế tốt hơn để xử lý vấn đề này.


3. Circuit Breaker Pattern
Khi cầu dao được đóng, dòng điện sẽ chạy qua, và khi mở thì dòng điện sẽ ngừng. Tương tự như thế, trong trường hợp này, một circuit breaker sẽ hoạt động như một chiếc cầu dao.
Nếu circuit breaker phát hiện service không phản hồi lại các request, nó sẽ mở ra, qua đó reject các request gửi tới service. Khi service hoạt động trở lại, circuit breaker sẽ đóng lại.

Để làm việc này thì CB cần liên tục kiểm tra service có đang hoạt động và phản hồi hay không. Khi đó service consumer chỉ cần xem CB đang mở hay đóng. Kết quả này có thể biết được ngay lập tức thay vì phải chờ 1 khoảng thời gian timeout.

1636412858135.png

(ảnh: google)

CB có thể monitor service thông qua nhiều cách. Cách đơn giản nhất vẫn thường thấy là heartbeat message. Cách này thì chỉ cho chúng ta biết service có đang alive hay không. Ngoài ra ta có thể fake request để gửi tới service, qua đó kiểm tra thông tin service trả về. Một cách thứ ba là real-time user monitoring, theo dõi trực tiếp khả năng đáp ứng của service. Nếu đạt tới một ngưỡng, CB sẽ chuyển sang trạng thái hoạt động một nửa, chỉ 1 số giao dịch được thực hiện. Khi service hoạt động lại bình thường, Cb sẽ đóng lại cho phép mọi request được thực hiện như bình thường.

Nguồn tham khảo:
Xin trước cái tit này nhé "To The Moon"
 
Last edited:
Bác có thể nói cụ thể một chút cái phần "được mô hình hóa dựa trên domain business" em khá tò mò về phần này. Có phải bác đang nói tới DDD không ạ
 
Nhân tiện thím đề cập đến akka, cho mình hỏi là akka có được sử dụng trong production nào nổi nổi không? Mình chưa gặp akka trong production nào cả?
 
Bác có thể nói cụ thể một chút cái phần "được mô hình hóa dựa trên domain business" em khá tò mò về phần này. Có phải bác đang nói tới DDD không ạ
1636504911925.png

có nhiều cách để theo system pattern này nha thím ... cái thím trên đang nói về domain thì đúng là cần đọc DDD để hiểu thêm.
 
cá nhân mình góp ý thớt nên gạch đầu dòng mấy cái lợi-hại sau đó hẵng ví dụ ... không thì ngc lại ... mà có cảm giác thớt kiểu đang giới thiệu sơ qa ấy nhỉ? đọc cái tít le tưởng bài dài lắm chứ =((=((=((
 
Hôm bữa đi phỏng vấn có gặp trường hợp "Làm thế nào để biết DB, hoặc App vẫn healthy trong mô hình đơn giản Web => App => DB".

Mình có trả lời là dùng healthcheck, web check app, app check DB, hoặc không thì một thằng thứ ba để check và self healing nhưng vẫn chưa phải là best pratice. Do bên phỏng vấn bận nên kết thúc sớm, mình cũng không có thời gian hỏi lại được.

:beat_brick:
 
Bác có thể nói cụ thể một chút cái phần "được mô hình hóa dựa trên domain business" em khá tò mò về phần này. Có phải bác đang nói tới DDD không ạ

Phần đó cũng khá dài, từ từ mình sẽ update. Các bác cứ chê ngắn chứ mình nói thật là các bác cứ thử viết đi sẽ hiểu. Viết ngắn thì ko đủ ý. Viết dài mà sai lại mất công ăn gạch :v Chưa kể tốn thời gian phết đó.

Góp ý về trình bày mình sẽ lưu ý và chỉnh lại nhé.
 
Hôm bữa đi phỏng vấn có gặp trường hợp "Làm thế nào để biết DB, hoặc App vẫn healthy trong mô hình đơn giản Web => App => DB".

Mình có trả lời là dùng healthcheck, web check app, app check DB, hoặc không thì một thằng thứ ba để check và self healing nhưng vẫn chưa phải là best pratice. Do bên phỏng vấn bận nên kết thúc sớm, mình cũng không có thời gian hỏi lại được.

:beat_brick:

Như trong bài mình có đề cập. Heath check qua heartbeat message là 1 giải pháp. Nó thường xác định là server có hoạt động hay ko. Còn để check nội dung trả về thì fake transaction nhé.

Ngoài ra, monitoring/alerting các tham số như CPU/Ram/Disk cũng là một việc quan trọng cần làm.

Bản chất cái heartbeat message cũng rất phức tạp. Ví dụ bạn gửi 100 cái heartbeat message, có thể dựa vào thời gian gửi và nhận request để tính toán và xác định trạng thái của server.
Việc đặt timeout chỉ là 1 giải pháp khá là "naive" thôi.
 
K nổi ở VN, nhưng cty em cũng đang dùng Akka stream processing cho hệ thống QRPay Nhật Bổn. Nói chung là cũng nhiều ưu điểm, tiện nhất là nó tự động back pressure cho mình
:D
có thể chia sẻ kỹ hơn đc ko bạn. Làm 1 thread tặng title cũng ok nhé.
 
Lý thuyết có vẻ cũ và ko thực tế, mấy cái cb với timeout kia có tác dụng gì. Stateless thì ko nói

Bên khách của tôi thì spring boot app deploy trên kubenetes của aws, nhiều service chia theo nhiều namespace

Mỗi service 1 db riêng. Giao tiếp qua activemq, hoặc rest api, chủ yếu activemq

Front end là angular deploy trên cloud front

Tích hợp okta, và đủ thứ của aws

//micro services mà ko có khả năng deploy trên cloud thì vất
 
Lý thuyết có vẻ cũ và ko thực tế, mấy cái cb với timeout kia có tác dụng gì. Stateless thì ko nói

Bên khách của tôi thì spring boot app deploy trên kubenetes của aws, nhiều service chia theo nhiều namespace

Mỗi service 1 db riêng. Giao tiếp qua activemq, hoặc rest api, chủ yếu activemq

Front end là angular deploy trên cloud front

Tích hợp okta, và đủ thứ của aws

//micro services mà ko có khả năng deploy trên cloud thì vất

Akka đang xài
Netflix đang xài.

Anh này lại bảo cũ và ko thực tế. :)

Cứ cho là giờ anh vứt hết lên cloud và ko cần care thì phía cloud nó implement kiểu gì anh biết ko?
AWS của anh đây hơi khác tí với lý thuyết nhưng tư tưởng thì tương tự.

https://aws.amazon.com/blogs/containers/announcing-amazon-ecs-deployment-circuit-breaker/
 
Last edited:
Bác nhầm, k có circuit breaker thì bác dùng activemq sao control được tốc độ consume message của microservice dc.

Giả sử bác đang consume từ queue, xong gọi api sang service khác, service kia chết thì bác xử lý kiểu gì.
Cái này là team architect với tư vấn viên của aws làm, tôi code thôi, 1 năm nay ko nhìn thấy 2 post api call, hoặc vừa consume queue rồi post sang chỗ khác

Có 1 app dùng atomikos để làm transaction cho 2 db, 1 activemq.

Hệ thống to, nhưng architecture đơn giản nhất có thể

Mấy cái nhận post api là input cho third party, lưu vào db, rồi đẩy vào queue hoặc chạy batch. Nó tránh hết transaction giữa các service, có thể nói là ko có cũng dc

Tôi vừa làm 1 cái app apache camel, làm đúng 1 việc là transform message, nhận từ 1 queue, convert, đẩy sang 1 queue khác
 
Last edited:
Akka đang xài
Netflix đang xài.

Anh này lại bảo cũ và ko thực tế. :)

Cứ cho là giờ anh vứt hết lên cloud và ko cần care thì phía cloud nó implement kiểu gì anh biết ko?
AWS của anh đây hơi khác tí với lý thuyết nhưng tư tưởng thì tương tự.

https://aws.amazon.com/blogs/containers/announcing-amazon-ecs-deployment-circuit-breaker/
Netflix làm lâu rồi, trước khi có kubernetes

Akka code khó bỏ mẹ

Cái spring cloud dùng netflix ấy, để deploy ở máy công ty thôi. Maintain khó vãi loàn ra, lên cloud thì dùng service của cloud tốt hơn nhiều chứ
 
Bác vẫn chưa trả lời dc. Nếu có dependency service chết, thì bác handle kiểu gì?
Giả sử bác ETL đi nữa thì cái queue ở sau nó chết thì bác làm sao để dừng consume up stream queue? rồi sau phục hồi dc?

Queue sau chết thì message nó vào queue lỗi. Mỗi input queue có 1 queue lỗi nữa để lưu message lỗi

Tôi làm happy case thôi. Có nhiều team động vào các case khác nhau. Architect, db, aws deploy, monitor, qa
 
CB là một cái pattern rất hay ho, nếu mà hay làm API composition hay aggregation thể nào cũng gặp. Vì trong một batch nhiều API call như vậy xui có 1 thằng nó chết toi thì ít nhất cũng phải trả dc default data :big_smile:
 
Back
Top