Tiếp tục phần 1, bài này tiếp tục trình bày giải pháp logging service chi tiết hơn về deployment và implementation
Sau khi lựa chọn giải pháp implement service log, team nghiên cứu architect của service logging. Một số pattern architect được xem xét như MVC, Clean Architect, controller service repository. Các technical stack cũng được thử nghiệm như Java, .Netcore, .nodejs
Sau nhiều đánh giá, team quyết định sử dụng clean architect và .netcore cho service logging.
Architect
Nói sơ qua về kiến trúc Clean Architect, đây là mô hình gồm các layer từ Web, Controller, Uses Cases, Entities phụ thuộc theo hướng từ ngoài vào trong, từ cao xuống thấp
Ví dụ Entities là business logic là lõi core, ko phụ thuộc vào layer nào.
Uses cases phụ thuộc vào entities only
Các layer ngoài cùng cũng tương tự như vậy.
Mấy kiến thức lý thuyết thì độc giả cứ lên GG tra cứu.
Còn giải thích theo kiểu giaosucan’s blog thì hiểu đơn giản thế này
Clean Architect cũng giống như cái nhà nhiều tầng từ 1 đến 4. Thì tầng 1 là tầng core business, tầng 4 là tầng web.
Rõ ràng tầng 1 là quan trọng nhất vì nó đỡ cả 3 tầng trên, muốn lên tầng 3 kiểu gì cũng phải đi qua tầng 1 rồi tầng 2 mới đến 3. Tức là tầng ngoài cùng dependency với các tầng dưới.
Tầng 4 dependency với 1, 2, 3.
Tầng 3 dependency với tầng 1, 2
Tầng 2 dependency với tầng 1
Tầng 1 không dependency với tầng nào cả
Khi vào bài toán thực tế số tầng có thể thay đổi nhiều hơn hoặc ít hơn nhưng nguyên tắc dependency phải giữ nguyên.
Team thiết kế architect của service có 1 số điều chỉnh cho phù hợp với 3 tầng như dưới
Layer web define các api post log
Core define entities, service để thực hiên log logging (push log vào rabbitmq)
Infrastructure xử lý giao tiếp với external như DB
Implementation
Về basic thì việc implement vẫn theo các pattern cơ bản, nên bài viết này không giải thích nhiều. Có 1 điểu khác biệt ở đây là cách xử lý api post log
Các app gọi đẩy log tới service log bằng gọi rest API kiểu như /api/v1/log rồi truyền body là json log data như env, log message, log type …
Controller invoke tầng service để thực hiện push log vào rabbitmq (dùng rabbitmq API) rồi return kết quả
Tuy nhiên cách này sẽ có rủi ro như sau
Số lượng request API Logging service rất lớn, nếu mỗi lần gọi api lại push log rabbit như trên, trong trường hợp rabbitmq service bị lỗi, việc push log có thể bị timeout. Trong khi service log chưa hoàn thành việc push log thì log mới liên tục được các app đẩy vào có thể gây nghẽn cổ chai và mất log.
Giải pháp được đưa ra, đó là sử dụng một ConcurrentBag. Một dạng list thread-safe trong C#. Khi log được đẩy tới, log object sẽ được push thẳng vào conccurentbag này. Một thread background sẽ chạy ngầm làm việc take từng object ra để đẩy vào queue
Về phần app, việc ghi log thực chất là gọi API restful request. Tuy nhiên không thể implement trực tiếp việc gọi API này trong app được vì lí do sau
Nếu có thay đổi gì về API ghi log (parameter, endpoint, payload etc…) phải sửa lại môt loạt trên các app
Duplicate code vi phạm DRY trong coding
Giải pháp đưa ra là implement một nudget library, một dạng wrapper việc call API rồi add vào từng project app như thư viện. Developer muốn ghi log thì chỉ việc gọi hàm hiểu log.debug(), log.info như các framework log thông thường là được
Deployment
Logging service được build thành docker rồi deploy lên K8S, dùng ingres controller
Bài tiếp theo sẽ trình giải pháp Logstash & RabbitMQ để lấy log từ rabbitmq đẩy vào ES
1 Nhận xét
Rất tuyệt vời, thưa Giáo sư !
Trả lờiXóa