Kiến trúc Microservices (MSA, Microservices Architecture)
1. Tổng quan
Kiến trúc microservices (MSA) là một phong cách kiến trúc cấu thành một hệ thống nghiệp vụ từ tập hợp các dịch vụ nhỏ có thể phát triển, triển khai, mở rộng độc lập, và kết nối các dịch vụ với nhau bằng hợp đồng tường minh và giao tiếp mạng.
Hệ thống nguyên khối (monolithic) truyền thống được build và triển khai như một đơn vị ứng dụng duy nhất. Giai đoạn đầu, đường gọi đơn giản và dễ xử lý giao dịch trên một cơ sở dữ liệu nên năng suất cao. Tuy nhiên khi tổ chức và chức năng lớn dần, phạm vi thay đổi mở rộng và ngay cả sửa đổi nhỏ cũng đòi hỏi triển khai toàn bộ và kiểm thử hồi quy. Tải của một chức năng cụ thể dẫn đến việc phải mở rộng toàn bộ ứng dụng, và xuất hiện vấn đề liên kết chặt khiến sự cố lan sang các chức năng khác.
MSA là cách tiếp cận giải quyết vấn đề này bằng cách phân rã thành ranh giới dịch vụ theo đơn vị năng lực nghiệp vụ (business capability). Dịch vụ có mã nguồn, đơn vị triển khai và quyền sở hữu dữ liệu riêng, chỉ công bố ra ngoài những hợp đồng cần thiết. Nhờ đó tổ chức có thể chọn công nghệ và chu kỳ triển khai khác nhau cho từng dịch vụ, và chỉ mở rộng theo chiều ngang những dịch vụ tập trung lưu lượng.
Tuy nhiên, MSA không đơn thuần là chia ứng dụng thành nhiều tiến trình. Do gọi mạng, giao dịch phân tán, nhất quán dữ liệu, khả năng quan sát, bảo mật, tự động hóa vận hành được đưa vào cùng lúc, độ phức tạp của toàn hệ thống tăng lên. Dịch vụ nhỏ nhiều lên nhưng nếu không quản lý được triển khai, sự cố và luồng dữ liệu thì vận hành còn khó hơn cả hệ thống nguyên khối.
Do đó, trong bài làm của Kỹ sư chuyên nghiệp (Professional Engineer), thay vì khẳng định "cứ phân rã là tốt", cần giải thích từ góc độ kiến trúc tại sao phải chia ranh giới, cho phép loại liên kết nào và kiểm soát thất bại của môi trường phân tán ra sao.
1.1 Bối cảnh ra đời và sự cần thiết
Thứ nhất, tốc độ thay đổi của kinh doanh đã tăng nhanh. Nếu gộp các chức năng có tần suất thay đổi và mức rủi ro khác nhau như thanh toán, thành viên, đơn hàng, gợi ý vào một bản phát hành, toàn bộ lịch trình sẽ phải theo phần chậm nhất. Triển khai độc lập theo dịch vụ thu hẹp phạm vi ảnh hưởng của thay đổi, cho phép thử nghiệm và phát hành từng bước.
Thứ hai, đặc tính khối lượng công việc đã khác nhau. Tìm kiếm thiên về đọc, thanh toán coi trọng tính nhất quán và truy vết kiểm toán, còn xử lý ảnh có thể cần nhiều tài nguyên CPU, GPU. Khó phản ánh hiệu quả những khác biệt này bằng cùng một chính sách mở rộng của một tiến trình duy nhất.
Thứ ba, trong tổ chức quy mô lớn, chi phí giao tiếp giữa các nhóm trở thành nút thắt hơn cả mã nguồn. Làm rõ ranh giới dịch vụ và hợp đồng API giúp phạm vi trách nhiệm của nhóm rõ ràng, nhóm có thể lập kế hoạch, phát triển, vận hành độc lập. Tuy nhiên không được để cơ cấu tổ chức quyết định ranh giới dịch vụ một cách gượng ép, mà phải phân tích trước mức độ liên kết miền thực tế và quyền sở hữu dữ liệu.
1.2 Đặc tính cốt lõi
Đặc tính thứ nhất của MSA là tính độc lập của dịch vụ. Độc lập không chỉ có nghĩa là kho mã nguồn được tách riêng, mà là dịch vụ có thể được build, kiểm thử và triển khai độc lập. Nếu một dịch vụ phụ thuộc vào bảng nội bộ hay thứ tự triển khai của dịch vụ khác thì dù tách biệt về logic, nó vẫn liên kết về mặt vận hành.
Đặc tính thứ hai là hợp đồng tường minh. Dù dùng phương thức giao tiếp nào như REST, gRPC, sự kiện thông điệp, định dạng yêu cầu/phản hồi, ý nghĩa lỗi, khả năng tương thích phiên bản, yêu cầu bảo mật đều phải được quản lý như hợp đồng. Nếu không duy trì hợp đồng bằng tài liệu và kiểm tra tự động, số dịch vụ càng tăng thì xung đột thay đổi càng lớn.
Đặc tính thứ ba là tính tự chủ dữ liệu. Mỗi dịch vụ sở hữu mô hình dữ liệu mình chịu trách nhiệm và không để dịch vụ khác truy vấn trực tiếp schema nội bộ. Nguyên tắc này buộc chấp nhận trùng lặp dữ liệu và nhất quán cuối cùng, nhưng giảm liên kết giữa các dịch vụ và cho phép thay đổi độc lập.
2. Cấu trúc tham chiếu và phân rã dịch vụ
2.1 Sơ đồ khái niệm kiến trúc tổng thể
flowchart LR
U[Người dùng, kênh bên ngoài] --> G[API Gateway / BFF]
G --> O[Dịch vụ đơn hàng]
G --> M[Dịch vụ thành viên]
G --> P[Dịch vụ thanh toán]
G --> S[Dịch vụ tìm kiếm]
O --> OB[(DB đơn hàng)]
M --> MB[(DB thành viên)]
P --> PB[(DB thanh toán)]
S --> SB[(Chỉ mục tìm kiếm)]
O --> B[Event broker]
P --> B
B --> N[Dịch vụ thông báo]
B --> A[Nền tảng phân tích, dữ liệu]
G --> X[Nền tảng quan sát tích hợp]
O --> X
M --> X
P --> X
Trong cấu trúc trên, gateway đảm nhận xác thực client bên ngoài, định tuyến, giới hạn tốc độ và chính sách chung. Tuy nhiên nếu đưa mọi logic nghiệp vụ vào gateway thì nó thành một khối nguyên khối mới, vì vậy quy tắc miền phải được giữ trong từng dịch vụ. Nếu cần tổ hợp chuyên biệt cho giao diện di động, web thì đặt BFF riêng, nhưng phân định ranh giới để BFF không trở thành chủ sở hữu dữ liệu cốt lõi.
Các dịch vụ đơn hàng, thành viên, thanh toán mỗi dịch vụ sở hữu kho dữ liệu của mình. Ở đây công nghệ lưu trữ không nhất thiết phải khác nhau. Điều quan trọng là dịch vụ khác không sửa trực tiếp hay join bảng, mà truy cập thông qua API hoặc sự kiện do dịch vụ sở hữu định nghĩa.
Event broker truyền kết nối bất đồng bộ và thay đổi trạng thái giữa các dịch vụ. Khi dịch vụ đơn hàng phát sự kiện tạo đơn hàng, dịch vụ thông báo và phân tích có thể xử lý theo tốc độ riêng. Tuy nhiên nếu giả định sự kiện chỉ được chuyển đúng một lần sẽ phát sinh trùng lặp hoặc lỗi xử lý lại, vì vậy phải thiết kế khóa idempotency, thử lại, thời gian lưu giữ, yêu cầu thứ tự.
Nền tảng quan sát tích hợp liên kết log, metric, trace vượt qua ranh giới dịch vụ. Không có ID tương quan của distributed trace thì khó nắm được một yêu cầu của người dùng bị trễ ở dịch vụ nào. Trong MSA, khả năng quan sát không phải chức năng vận hành phụ trợ mà là thành phần kiến trúc cơ bản.
2.2 Nguyên lý xác định ranh giới dịch vụ
Ranh giới dịch vụ được xác định theo năng lực nghiệp vụ miền chứ không theo tầng kỹ thuật. Nếu chia theo tầng như "dịch vụ controller", "dịch vụ cơ sở dữ liệu", một yêu cầu nghiệp vụ sẽ gọi qua nhiều dịch vụ, lưu lượng giao tiếp và chi phí điều phối giữa các dịch vụ tăng vọt. Ngược lại, các đơn vị có trách nhiệm nghiệp vụ và lý do thay đổi khác nhau như đơn hàng, tồn kho, giao hàng là ứng viên ranh giới.
Bounded context của thiết kế hướng miền (DDD) là khung tư duy hữu ích cho việc xác định ranh giới. Nếu cùng một từ mang ý nghĩa khác nhau tùy ngữ cảnh thì tách mô hình. Ví dụ, khách hàng trong marketing là đối tượng phân khúc, trong thanh toán là chủ thể bị tính phí, trong giao hàng có thể là người nhận. Nếu hợp nhất thông tin khách hàng của mọi ngữ cảnh vào một mô hình khách hàng khổng lồ, ảnh hưởng của thay đổi sẽ lớn.
Đánh giá đồng thời độ gắn kết và độ liên kết. Các chức năng phải thay đổi và triển khai cùng nhau nên đặt trong cùng dịch vụ, còn các chức năng có nhóm, lịch trình, đặc tính sự cố khác nhau là ứng viên tách. Nếu chỉ nhìn tần suất gọi để tách thì số lượt khứ hồi mạng có thể quá mức, vì vậy ưu tiên xem xét ranh giới luồng nghiệp vụ và yêu cầu nhất quán dữ liệu.
Kết quả phân rã không hoàn thành trong một lần. Phương pháp quan sát điểm thay đổi trong mã nguyên khối và trích xuất dần từ năng lực nghiệp vụ ưu tiên cao bằng mẫu strangler sẽ giảm rủi ro. Trước khi dịch vụ được trích xuất ổn định, cần chuẩn bị feature flag, kiểm chứng song song, đường rollback.
2.3 Vai trò của từng thành phần
| Thành phần | Vai trò chính | Câu hỏi cốt lõi khi thiết kế |
|---|---|---|
| Dịch vụ | Hiện thực năng lực nghiệp vụ và sở hữu dữ liệu | Triển khai độc lập và phạm vi trách nhiệm có rõ ràng không? |
| API Gateway | Điểm vào bên ngoài, định tuyến, chính sách chung | Chính sách và logic nghiệp vụ có bị trộn lẫn không? |
| Service mesh | Chính sách giao tiếp giữa dịch vụ, bảo mật, quan sát | Độ phức tạp vận hành proxy có lớn hơn lợi ích không? |
| Event broker | Chuyển giao bất đồng bộ và đệm | Bảo đảm trùng lặp, thứ tự, xử lý lại như thế nào? |
| Kho lưu trữ theo dịch vụ | Sở hữu dữ liệu và tối ưu mô hình | Đã chặn truy cập trực tiếp của dịch vụ khác chưa? |
| CI/CD | Tự động hóa build, kiểm thử, triển khai | Có pipeline và cổng chất lượng theo dịch vụ không? |
| Nền tảng quan sát | Tích hợp log, metric, trace | Có truy vết được tương quan yêu cầu không? |
Các thành phần trong bảng không phải danh sách sản phẩm đưa vào độc lập. Ví dụ, dù cài event broker, nếu không có quyền sở hữu dữ liệu giữa các dịch vụ và chính sách xử lý lại thì chỉ khiến xử lý thông điệp phức tạp thêm. Ngược lại, khả năng quan sát chỉ hiệu quả khi xác định trường chuẩn và quy tắc lan truyền trace trước khi số dịch vụ tăng lên.
3. Giao tiếp và quản lý dữ liệu
3.1 Lựa chọn giao tiếp đồng bộ, bất đồng bộ
Gọi đồng bộ phù hợp cho tra cứu cần phản hồi ngay hoặc kiểm tra ngắn. Bên gọi có thể nhận kết quả rồi quyết định xử lý tiếp theo, và giao diện trực quan. Tuy nhiên nếu đích gọi bị trễ hay gặp sự cố, luồng và tài nguyên của bên gọi cũng bị giữ theo. Chuỗi gọi càng dài, sự cố cục bộ càng lan thành thất bại của toàn bộ yêu cầu.
Thông điệp bất đồng bộ giảm liên kết thời gian giữa các dịch vụ. Nếu không cần hoàn tất thông báo ngay sau khi tạo đơn hàng, dịch vụ đơn hàng có thể phát sự kiện và để dịch vụ thông báo xử lý sau. Đổi lại, phải đối phó với chuyển trùng lặp, đảo thứ tự, độ trễ của bên tiêu thụ, mất thông điệp.
Trong thực tế, không chọn loại giao tiếp theo lối nhị phân. Các bước cốt lõi cần kết quả ngay như phê duyệt thanh toán của người dùng được xử lý bằng gọi đồng bộ với timeout giới hạn, còn gửi biên lai, cập nhật gợi ý, nạp dữ liệu phân tích được tách thành sự kiện. Cần chọn phương thức giao tiếp dựa trên định nghĩa hoàn tất của nghiệp vụ và quy trình bù khi thất bại.
| Phân loại | API đồng bộ | Thông điệp bất đồng bộ |
|---|---|---|
| Khả năng phản hồi | Xác nhận kết quả tại thời điểm gọi | Xác nhận kết quả xử lý sau |
| Mức liên kết | Liên kết thời gian lớn | Liên kết thời gian nhỏ |
| Lan truyền sự cố | Có thể dây chuyền timeout | Có thể đệm bằng cách nạp vào hàng đợi |
| Tính nhất quán | Dễ kiểm tra ngay | Cần thiết kế nhất quán cuối cùng |
| Độ khó vận hành | Tập trung vào gọi, thử lại | Cần quản lý broker, xử lý lại, thứ tự |
3.2 Nhất quán dữ liệu và giao dịch phân tán
Khi dùng cơ sở dữ liệu riêng cho mỗi dịch vụ trong MSA, khó gộp nhiều dịch vụ vào một giao dịch ACID. Ví dụ, nếu cố xử lý lưu đơn hàng, trừ tồn kho, phê duyệt thanh toán trong một lần commit sẽ phát sinh liên kết chặt giữa các dịch vụ và vấn đề khóa khi có sự cố. Vì vậy thiết kế cấu trúc chia nghiệp vụ thành giao dịch cục bộ và chuyển trạng thái, bù khi thất bại.
Saga là mẫu cấu thành nghiệp vụ phân tán từ nhiều giao dịch cục bộ, và khi bước giữa thất bại thì thực hiện giao dịch bù để hoàn lại các tác vụ đã hoàn tất. Phương thức orchestration có bộ điều phối trung tâm chỉ thị bước tiếp theo nên luồng và xử lý thất bại rõ ràng. Phương thức choreography để dịch vụ phản ứng với sự kiện nên liên kết thấp, nhưng khó nắm toàn bộ luồng trong một cái nhìn.
Bù khác với rollback vật lý của cơ sở dữ liệu. Nếu thanh toán bên ngoài đã được phê duyệt thì không thể đơn giản xóa dòng mà phải thực hiện nghiệp vụ riêng là hủy thanh toán. Do đó, an toàn hơn khi định nghĩa thành máy trạng thái bao gồm cả khả năng bù, thực thi trùng lặp, giới hạn thời gian, biện pháp thủ công của người vận hành.
Mẫu outbox giảm sự bất nhất giữa thay đổi dữ liệu và phát sự kiện. Dịch vụ lưu dữ liệu nghiệp vụ và sự kiện cần phát trong cùng một giao dịch cục bộ, rồi một bộ phát riêng chuyển bản ghi outbox tới broker. Có thể quản lý việc chuyển thành công hay không và phát trùng lặp, nhưng phải thiết kế kèm xử lý idempotent phía bên tiêu thụ.
3.3 Luồng xử lý Saga, outbox
sequenceDiagram
participant C as Dịch vụ đơn hàng
participant O as DB đơn hàng
participant X as Outbox relay
participant Q as Event broker
participant I as Dịch vụ tồn kho
participant P as Dịch vụ thanh toán
C->>O: Tạo đơn hàng + lưu OrderCreated
X->>O: Tra cứu sự kiện chưa phát
X->>Q: Phát OrderCreated
Q->>I: Lệnh đặt giữ tồn kho
Q->>P: Lệnh phê duyệt thanh toán
I-->>Q: StockReserved hoặc StockRejected
P-->>Q: PaymentApproved hoặc PaymentRejected
Q->>C: Chuyển sự kiện chuyển trạng thái
C->>O: Ghi trạng thái đơn hàng hoàn tất, thất bại
Trong luồng này, nếu dịch vụ đơn hàng lưu đơn hàng rồi tự phát sự kiện trực tiếp qua mạng, sẽ có khe hở giữa việc commit dữ liệu thành công và phát thành công. Outbox relay đọc lại sự kiện đã được lưu trong cùng giao dịch cục bộ để phát nên thu hẹp khe hở này. Nếu relay gặp sự cố sau khi phát, cùng một sự kiện có thể được gửi lại, vì vậy phải bảo đảm idempotency phía tiêu thụ dựa trên ID sự kiện.
Kết quả tồn kho và thanh toán có thể đến độc lập. Dịch vụ đơn hàng không giả định thứ tự đến của sự kiện luôn cố định, mà kiểm tra quy tắc chuyển trạng thái và các chuyển trạng thái không được phép. Ví dụ, dù phê duyệt thanh toán đến trước, nếu đặt giữ tồn kho thất bại thì phải thực hiện bù hủy thanh toán rồi chuyển đơn hàng sang trạng thái thất bại.
3.4 Hợp đồng API và quản lý phiên bản
Hợp đồng bao gồm không chỉ phản hồi bình thường mà cả mã lỗi, trường bắt buộc/tùy chọn, đơn vị thời gian, định dạng định danh, việc có chứa dữ liệu cá nhân hay không. Dù có tài liệu, nếu lệch với hiện thực thực tế thì không phải hợp đồng, vì vậy nối kiểm thử hợp đồng dựa trên schema và kiểm thử hợp đồng hướng bên tiêu thụ vào CI.
Xét đến khả năng tương thích ngược, không được đột ngột xóa hoặc đổi nghĩa trường hiện có. Khi thêm trường mới, để bên tiêu thụ có thể bỏ qua; loại bỏ trường thì sau khi xác nhận tình hình sử dụng mới qua các bước thông báo, giai đoạn song song, xóa. Lựa chọn giữa phiên bản URI, phiên bản header, thương lượng nội dung được áp dụng nhất quán theo chuẩn tổ chức và công cụ vận hành.
Không phải vì là dịch vụ nội bộ mà quản lý hợp đồng kém quan trọng hơn. Trái lại, khi có nhiều bên tiêu thụ nội bộ và chu kỳ triển khai khác nhau, việc truy vết ảnh hưởng thay đổi khó khăn. Quản lý danh sách bên gọi, chủ sở hữu hợp đồng, ngày dự kiến hết hạn, lịch sử thay đổi schema bằng catalog sẽ giảm phụ thuộc không chính thức.
4. Quản lý vận hành, bảo mật, chất lượng
4.1 Cô lập sự cố và khả năng phục hồi
Trong hệ thống phân tán, thất bại được xem là điều kiện thiết kế bình thường chứ không phải ngoại lệ. Lời gọi không đặt timeout sẽ chiếm giữ tài nguyên cho đến khi dịch vụ sự cố hồi phục, cuối cùng làm cạn kiệt cả dịch vụ bình thường. Mọi lời gọi từ xa cần thời gian giới hạn phù hợp với nghiệp vụ và đường thay thế khi thất bại.
Circuit breaker chặn lời gọi và cho thất bại nhanh khi số lần thất bại liên tiếp vượt ngưỡng. Pool gọi cách ly hay bulkhead ngăn việc cạn kiệt tài nguyên của một chức năng lan sang chức năng khác. Thử lại chỉ dùng hạn chế cho lỗi tạm thời, kèm exponential backoff và jitter để ngăn bão thử lại.
Tác vụ có thể thử lại phải là idempotent. Áp dụng thử lại đơn giản cho yêu cầu thanh toán có thể gây thanh toán trùng, nên cần khóa yêu cầu của client và lưu kết quả xử lý của máy chủ. Thiết kế phục hồi sự cố không phải là liệt kê tên mẫu kỹ thuật, mà là định nghĩa trải nghiệm người dùng và kết quả dữ liệu cho từng loại lỗi.
4.2 Chiến lược triển khai và cổng chất lượng
Triển khai độc lập theo dịch vụ giả định có pipeline build, kiểm thử, triển khai tự động. Bố trí phân tích tĩnh, kiểm thử đơn vị, kiểm thử hợp đồng, kiểm thử tích hợp, rà soát lỗ hổng theo mức rủi ro thay đổi, và trước khi triển khai vận hành bảo đảm artifact có thể hoàn lại và kế hoạch di chuyển dữ liệu.
Triển khai blue-green chuyển đổi giữa hai môi trường để cung cấp rollback nhanh. Triển khai canary đưa phiên bản mới cho một phần người dùng hay lưu lượng và so sánh tỷ lệ lỗi, độ trễ, chỉ số nghiệp vụ. Triển khai dần dần không kết thúc chỉ với định tuyến mạng, mà phải xác định dừng dựa trên chỉ số nào và giai đoạn tương thích dữ liệu.
Thay đổi schema dữ liệu tồn tại lâu hơn triển khai ứng dụng. Cách mở rộng - chuyển đổi - thu hẹp là an toàn: trước tiên thêm trường mới để cả hai phiên bản đọc được, rồi chuyển ứng dụng, sau đó mới xóa trường cũ không dùng. Nếu gộp thay đổi schema và triển khai mã trong một lần, rollback có thể bị chặn bởi cấu trúc dữ liệu.
4.3 Bảo mật và chuỗi cung ứng
Số dịch vụ tăng thì số điểm xác thực, phân quyền và thông tin bí mật cũng tăng theo. Phân biệt xác thực người dùng bên ngoài với xác thực giữa các dịch vụ, và thu hẹp quyền theo tài khoản dịch vụ theo nguyên tắc đặc quyền tối thiểu. Đặt mã hóa đường truyền, quản lý tập trung thông tin bí mật, thay khóa, log kiểm toán làm kiểm soát cơ bản.
Dùng service mesh có thể chung hóa mutual TLS và chính sách, nhưng phải quản lý quyền và cập nhật của chính proxy và control plane. Chỉ tin vào vị trí mạng là không đủ; cần xác nhận chủ thể gọi, đích, hành vi, cấp độ dữ liệu để đưa ra quyết định truy cập chi tiết.
Cũng cần rà soát lỗ hổng cho thư viện phụ thuộc và container image của từng dịch vụ. Liên kết danh sách thành phần phần mềm, chữ ký image, nguồn gốc build, lịch sử phê duyệt triển khai sẽ giúp nhanh chóng tìm dịch vụ bị ảnh hưởng khi phát hiện vấn đề.
4.4 Khả năng quan sát và mức dịch vụ
Log cho thấy ngữ cảnh sự việc, metric cho thấy xu hướng và ngưỡng, trace cho thấy đường đi và đoạn trễ của yêu cầu. Đưa cùng trace ID, tên dịch vụ, phiên bản, môi trường, định danh yêu cầu người dùng vào cả ba tín hiệu sẽ giảm thời gian phân tích nguyên nhân. Quy tắc che để không lưu dữ liệu cá nhân và thông tin bí mật vào log cũng được áp đặt ở thư viện chung hoặc giai đoạn thu thập.
Mục tiêu mức dịch vụ (SLO) phải liên kết chỉ số kỹ thuật với kết quả nghiệp vụ. Không chỉ xem tỷ lệ thành công của API đơn hàng mà xem cùng các chỉ số góc nhìn người dùng như tỷ lệ hoàn tất đơn hàng, tỷ lệ thất bại thanh toán, độ trễ xử lý. Nếu SLO của các dịch vụ xung đột nhau, điều chỉnh ưu tiên dựa trên mục tiêu của luồng nghiệp vụ cấp trên.
Error budget là cơ chế vận hành cân bằng độ ổn định và tốc độ thay đổi. Khi đã tiêu hết lượng thất bại cho phép, tạm điều chỉnh việc triển khai tính năng mới và đầu tư cải thiện khả năng phục hồi. Tuy nhiên, nếu bản thân con số trở thành mục đích thì chỉ số sẽ bị thao túng, nên phải xem xét cùng tác động nghiệp vụ của sự cố và trải nghiệm khách hàng.
5. So sánh và tình huống
5.1 So sánh nguyên khối, SOA, MSA
Nguyên khối có một đơn vị triển khai và tiến trình nên phát triển ban đầu và xử lý giao dịch đơn giản. Đổi lại, mã và dữ liệu càng lớn thì phân tích ảnh hưởng thay đổi và mở rộng có chọn lọc càng khó. MSA đạt được tính độc lập nhưng phải gánh độ phức tạp mạng và vận hành. SOA hướng tới hướng dịch vụ và tái sử dụng, nhưng nếu chính sách và chuyển đổi tập trung vào ESB trung tâm thì có thể phát sinh nút thắt và liên kết chặt.
| Góc nhìn | Nguyên khối | SOA | MSA |
|---|---|---|---|
| Đơn vị triển khai | Toàn bộ ứng dụng | Tổ hợp dịch vụ, ESB | Dịch vụ độc lập |
| Phương thức tích hợp | Gọi trong tiến trình | Tích hợp trung tâm và hợp đồng chuẩn | Tập trung API nhẹ, sự kiện |
| Dữ liệu | Thường là DB tích hợp | Có thể dùng chung dữ liệu | Nguyên tắc sở hữu theo dịch vụ |
| Mở rộng | Toàn bộ hoặc đơn vị lớn | Có thể theo dịch vụ | Mở rộng chính xác theo chức năng |
| Độ phức tạp vận hành | Tương đối thấp | Trung bình, phụ thuộc tích hợp trung tâm | Cao, bắt buộc tự động hóa |
| Tình huống phù hợp | Miền nhỏ và ổn định | Tích hợp, tái sử dụng giữa tổ chức | Thay đổi nhanh và vận hành quy mô lớn |
Cốt lõi của so sánh là không xếp hạng theo kiểu MSA là giai đoạn tiến hóa của khái niệm cấp trên. Hệ thống nhỏ tập trung vào giao dịch có thể kinh tế hơn với nguyên khối, còn tích hợp hệ thống không đồng nhất của nhiều tổ chức có thể có lợi với chính sách trung tâm của SOA. Cần đánh giá đồng thời tốc độ thay đổi nghiệp vụ, cơ cấu nhóm, năng lực vận hành, yêu cầu quy định để lựa chọn.
5.2 Tình huống đơn hàng thương mại điện tử
Trong thương mại điện tử, tạo đơn hàng nối tiếp xác nhận thành viên, đặt giữ tồn kho, phê duyệt thanh toán, yêu cầu giao hàng, gửi thông báo. Nếu gộp tất cả vào một giao dịch đồng bộ duy nhất, độ trễ của hệ thống thanh toán sẽ chặn toàn bộ đơn hàng, và khi lưu lượng tăng đột biến, tài nguyên kết nối có thể nhanh chóng cạn kiệt.
Luồng cải tiến là dịch vụ đơn hàng lưu đơn hàng ở trạng thái "chờ thanh toán" rồi phát yêu cầu phê duyệt thanh toán. Khi thanh toán được phê duyệt, sự kiện phê duyệt thanh toán được phát và dịch vụ tồn kho xác nhận đặt giữ. Nếu thiếu tồn kho thì phát sự kiện bù hủy thanh toán và chuyển trạng thái đơn hàng sang "thất bại".
Trong luồng này, người dùng phải thấy được trạng thái đang xử lý thay vì màn hình hoàn tất ngay lập tức. Cung cấp trạng thái từng bước, nút xử lý lại, quy trình hiệu chỉnh của người vận hành sẽ giúp hấp thụ nhất quán cuối cùng vào trải nghiệm người dùng. Sự kiện phải chứa ID đơn hàng, ID sự kiện, thời điểm phát sinh, phiên bản schema, và bên tiêu thụ loại bỏ trùng lặp bằng ID sự kiện.
5.3 Tình huống chuyển đổi từng bước
Phân rã một trang mua sắm nguyên khối hiện có thành dịch vụ trong một lần là rủi ro. Trước tiên tách chức năng tìm kiếm có tần suất thay đổi và ảnh hưởng sự cố cao thành dịch vụ chỉ đọc, xây dựng chỉ mục tìm kiếm bất đồng bộ từ dữ liệu hiện có. So sánh song song tính chính xác kết quả tìm kiếm trong một thời gian để xác nhận chất lượng rồi chuyển lưu lượng dần dần.
Tiếp theo, khi tách các vùng có yêu cầu nhất quán dữ liệu cao như đơn hàng và thanh toán, định nghĩa rõ ranh giới và thay thế các đường mà mã cũ truy vấn trực tiếp cơ sở dữ liệu bằng gọi API. Lúc này phải đo suy giảm hiệu năng và lan truyền sự cố; mục tiêu không phải đơn thuần là biến mọi lời gọi thành gọi mạng.
Tiêu chí hoàn tất chuyển đổi phải bao gồm khả năng triển khai độc lập, cô lập sự cố, trách nhiệm nhóm, chỉ số vận hành hơn là lượng mã được di chuyển. Nếu dịch vụ đã được trích xuất nhưng lần nào cũng triển khai cùng toàn hệ thống thì hiệu quả tách cấu trúc vẫn chưa được hiện thực.
6. Chuyên sâu: Tổ chức, nền tảng, liên hệ đề thi
Thành bại của MSA phụ thuộc vào chuẩn hóa nền tảng và trách nhiệm vận hành của nhóm hơn là mã của từng dịch vụ. Cung cấp template dịch vụ, thư viện xác thực chung, định dạng log, pipeline triển khai, dashboard cơ bản giúp nhóm không phải hiện thực lại chức năng nền tảng mỗi lần. Tuy nhiên nếu nền tảng chung áp đặt mọi lựa chọn công nghệ thì tính tự chủ biến mất, nên phải phân biệt kiểm soát bắt buộc và hiện thực có thể lựa chọn.
Mô hình DevOps trong đó nhóm phát triển chịu trách nhiệm cả vận hành giúp nhanh chóng học được nguyên nhân sự cố và tác động tới người dùng. Ngược lại, nếu ủy thác triển khai hàng loạt cho nhóm vận hành thì khó phản ánh đặc tính từng dịch vụ và hàng đợi triển khai lại xuất hiện. Trong thiết kế tổ chức, phải định nghĩa cùng lúc ranh giới dịch vụ, quyền sở hữu mã, trách nhiệm on-call, phân bổ chi phí.
Trong bài làm của Kỹ sư chuyên nghiệp, sau khi giải thích MSA, điều quan trọng là không chỉ lặp lại ưu điểm của microservice mà đưa ra luận điểm phản biện là giao dịch phân tán và độ phức tạp vận hành. Mạch bài làm sẽ logic nếu theo thứ tự bối cảnh và định nghĩa, nguyên tắc phân rã, giao tiếp và nhất quán dữ liệu, kiểm soát vận hành và bảo mật, áp dụng từng bước và quản lý rủi ro.
Đề thi dự kiến có thể ra dưới dạng "Các điểm cần xem xét khi chuyển đổi sang MSA", "So sánh nguyên khối và MSA", "Phương án bảo đảm nhất quán dữ liệu giữa các dịch vụ", "Khả năng quan sát và ứng phó sự cố trong môi trường MSA". Nếu mỗi đề đều liên kết chung căn cứ ranh giới dịch vụ, triển khai độc lập, quản lý hợp đồng, saga và outbox, khả năng quan sát, bảo mật, thay đổi tổ chức thì bài làm sẽ vượt qua việc giải thích thuật ngữ đơn thuần.
7. Các điểm cần lưu ý và hàm ý
7.1 Tính khả thi khi áp dụng
Không áp dụng MSA cho mọi hệ thống. Nếu miền nhỏ, ít thay đổi và chỉ có một hai nhóm thì kiểm chứng ranh giới trước bằng nguyên khối mô-đun sẽ kinh tế hơn. Nếu chi phí mạng và vận hành lớn hơn tính độc lập có được nhờ tách dịch vụ thì tính khả thi áp dụng là chưa đủ.
7.2 Ranh giới và quyền sở hữu dữ liệu
Ranh giới dịch vụ được xác định dựa trên năng lực nghiệp vụ và lý do thay đổi, không phải sơ đồ tổ chức hay cấu trúc bảng hiện tại. Phải làm rõ chủ sở hữu dữ liệu và cấm dịch vụ khác truy cập trực tiếp DB thì triển khai độc lập mới được duy trì. Khi cần dữ liệu trùng lặp, ghi lại thành văn bản mục đích sao chép và phạm vi chấp nhận về tính nhất quán.
7.3 Chuyển đổi từng bước và chất lượng
Chia rủi ro thành đơn vị nhỏ bằng mẫu strangler, feature flag, canary, kiểm chứng song song. So sánh độ trễ, tỷ lệ lỗi, tỷ lệ thành công nghiệp vụ trước và sau chuyển đổi, và diễn tập đường rollback cùng quy trình hiệu chỉnh dữ liệu. Áp dụng thành công được đo bằng việc cải thiện tác động sự cố và lead time thay đổi, không phải bằng việc tăng số dịch vụ.
7.4 Tự động hóa vận hành
Dịch vụ càng nhiều, triển khai thủ công và giám sát riêng lẻ càng chạm giới hạn. Cung cấp dưới dạng nền tảng pipeline chuẩn, tự động co giãn, mã hóa chính sách, log và trace tập trung, trực quan hóa chi phí. Giám sát cả thất bại của chính tự động hóa và kiểm toán quyền cùng lịch sử thay đổi.
7.5 Bảo mật và quy định
Lấy đặc quyền tối thiểu theo dịch vụ, xác thực lẫn nhau, quản lý thông tin bí mật, rà soát lỗ hổng làm kiểm soát cơ bản. Do dữ liệu cá nhân có thể bị sao chép qua sự kiện và log, cần thiết kế cấp độ dữ liệu, thời hạn lưu giữ, che giấu, lan truyền xóa. Với dữ liệu thuộc đối tượng quy định, ưu tiên kiểm soát truy cập và khả năng kiểm toán hơn sự tiện lợi của việc tách dịch vụ.
7.6 Hiệu năng, chi phí, tính bền vững
Gọi mạng, tuần tự hóa, proxy, lưu trữ log làm tăng chi phí và độ trễ trên mỗi yêu cầu. Không chia nhỏ lời gọi một cách vô điều kiện mà thiết kế đồng thời mẫu truy cập dữ liệu với cache, batch, xử lý bất đồng bộ. Theo dõi lượng tài nguyên sử dụng và chỉ số carbon, chi phí theo dịch vụ để đánh giá liệu mở rộng độc lập có thực sự dẫn tới giá trị kinh doanh hay không.
Tóm tắt một câu: MSA mang lại triển khai và mở rộng độc lập theo ranh giới miền, nhưng chỉ tạo ra giá trị khi được thiết kế đồng thời với nhất quán dữ liệu, cô lập sự cố, khả năng quan sát, bảo mật và vận hành tổ chức.