Bài toán thực tế
Toàn bộ hệ thống nằm chung trong một khối monolith .NET Framework 4.7 khiến mỗi đợt release đều tiềm ẩn rủi ro lan truyền sang mọi mảng nghiệp vụ, và mỗi lần deploy đầy đủ mất khoảng 2 giờ thao tác thủ công.
Kiến trúc hệ thống
flowchart LR
subgraph legacy ["Legacy monolith"]
legacy_0[".NET Framework 4.7 monolith"]
legacy_1["Manual deploy pipeline"]
end
subgraph extract ["Strangler cut"]
extract_0["First domain service on .NET 7"]
extract_1["Traffic router or gateway"]
extract_2[("Shared DB phase")]
end
subgraph platform ["Event and ops"]
platform_0[["RabbitMQ event bus"]]
platform_1["CI build and test"]
platform_2["Automated deploy to EC2"]
platform_3["AWS standard template"]
end
legacy_0 --> extract_1
extract_1 --> extract_0
extract_0 --> extract_2
extract_0 --> platform_0
platform_1 --> platform_2
platform_3 --> platform_2Các quyết định kiến trúc then chốt
Bóc tách dần theo mảng nghiệp vụ (Strangler pattern), không đập đi xây lại
Triển khai các service .NET 7 mới chạy song song cạnh khối monolith và điều hướng lưu lượng truy cập (traffic) sang dần.
Đóng băng hệ thống để viết lại từ đầu sẽ làm đình trệ việc sửa lỗi và phát triển tính năng cho các khách hàng đang trả phí.
Phương án đã loại bỏ: Đập đi xây lại toàn bộ (big-bang rewrite) — loại bỏ vì rủi ro đứt gãy vận hành và thời gian chờ đợi quá lớn.
Đánh đổi: Chấp nhận chi phí vận hành song song hai hệ thống (dual-run) và dùng chung database tạm thời cho đến bước tách dữ liệu tiếp theo.
Chuyển sang bất đồng bộ (async end-to-end) trên các luồng nặng về I/O
Áp dụng async xuyên suốt từ tầng Web API xuống tầng truy xuất dữ liệu trên các luồng tải cao (hot paths); loại bỏ phụ thuộc vào session cố định trên từng máy chủ (session affinity) ở những nơi có thể.
Hiện tượng cạn kiệt luồng xử lý (thread pool starvation) khi tải tăng cao là điểm nghẽn kinh niên của khối monolith cũ.
Phương án đã loại bỏ: Gọi chặn đồng bộ (.Result / .Wait) bọc ngoài các hàm cũ — loại bỏ hoàn toàn trên các service mới sau nhiều lần gây deadlock trên .NET Framework.
Đánh đổi: Cần đào tạo lại thói quen viết code cho đội ngũ và rà soát kỹ các điểm gọi hàm còn nằm lại trong khối monolith.
Chuẩn hóa bộ khung AWS và CI/CD cho dự án mới
Đóng gói sẵn cấu hình EC2, security group, Docker Compose và danh mục kiểm tra CI thành một bộ template chuẩn để nhân bản cho mỗi dự án mới.
Trước đó mỗi dự án mới đều tự cấu hình lại chứng chỉ TLS và kịch bản deploy theo một kiểu khác nhau.
Phương án đã loại bỏ: Thiết kế hạ tầng tùy biến riêng lẻ cho từng dự án — loại bỏ sau khi liên tục làm chậm tiến độ khởi tạo dự án hàng tuần liền.
Đánh đổi: Cần có người chịu trách nhiệm duy trì và cập nhật template chung; mọi trường hợp ngoại lệ đều phải ghi rõ lý do kỹ thuật.
Phần tôi chịu trách nhiệm, trực tiếp viết và phân công
Chịu trách nhiệm (Own)
- Chiến lược chuyển đổi (migration strategy) và lựa chọn mảng nghiệp vụ đầu tiên để bóc tách
- Chuẩn hóa quy trình CI/CD và bộ template hạ tầng AWS cho việc khởi tạo các dự án mới
- Đầu mối kỹ thuật chính (technical point of contact) cho 5 khách hàng doanh nghiệp trong suốt giai đoạn chuyển đổi
Trực tiếp viết (Write)
- Các service .NET 7 đầu tiên được tách ra và lớp tích hợp ngược lại với khối monolith còn lại
- Các luồng giao tiếp bất đồng bộ (event-driven) qua RabbitMQ ở những nghiệp vụ cần tách rời
Phân công (Delegate)
- Đàm phán thương mại và quản lý tài khoản khách hàng (account management)
Quy mô vận hành
- Thời gian deploy khối monolith giảm từ ~2 giờ thao tác thủ công xuống ~15 phút sau khi có CI/CD và tách nhỏ service
- Thời gian dựng hạ tầng AWS cho dự án mới rút ngắn từ vài tuần xuống còn vài ngày nhờ bộ template chuẩn
- Trực tiếp làm đầu mối kỹ thuật xử lý sự cố cho 5 khách hàng doanh nghiệp lớn
Ranh giới phạm vi
- Khả năng chịu tải được cải thiện qua nhiều lớp kết hợp (chuyển sang async I/O, đưa session state ra ngoài tiến trình, bổ sung cache, tối ưu index và nâng cấp runtime), không đến từ một phép thử đơn lẻ nào.
- Quá trình chuyển đổi lưu lượng (cutover) không phải lúc nào cũng là zero-downtime rolling deploy cho toàn bộ mọi service.
Các chỉ số giám sát khi vận hành
Nguyên tắc bất di bất dịch trong thiết kế
- Việc deploy một mảng nghiệp vụ riêng lẻ không bao giờ được phép làm gián đoạn toàn bộ khối monolith.
- Mọi thay đổi trên schema dữ liệu dùng chung đều phải được phối hợp kiểm soát; các service không được tự ý thay đổi ngữ nghĩa của dữ liệu hiện có.
- Mỗi khách hàng doanh nghiệp đều có đầu mối kỹ thuật định danh trực tiếp hỗ trợ trong khung giờ chuyển đổi, không đẩy qua hàng đợi ticket chung.
Phạm vi ứng dụng rộng hơn
- Các hệ thống .NET Framework lâu năm cần hiện đại hóa mà không được làm gián đoạn dòng doanh thu.
- Tổ chức kỹ thuật muốn chuẩn hóa quy trình đưa dự án mới lên cloud thay vì làm thủ công.
- Đội ngũ kỹ sư chuyển dịch từ thói quen phát hành monolith sang kiến trúc microservices.