01 Microservices là gì?
Lấy cảm hứng mạnh từ Bounded Context (DDD): mỗi service hạt mịn, một mục đích, triển khai độc lập, và sở hữu dữ liệu riêng. Là "hiện thân vật lý" của các khái niệm logic trong domain-driven design — đẩy domain partitioning tới cực hạn.
Microservices ưa trùng lặp hơn ghép nối — thà nhân bản dữ liệu còn hơn chia sẻ schema/lớp để rồi dính chặt vào nhau.
Triết lý "share nothing"Nhớ Entity Trap (topic 04): đừng mô hình hoá service giống hệt từng bảng DB. Service là bounded context (luồng nghiệp vụ), không phải "Manager theo thực thể".
02 Bốn nguyên tắc cốt lõi
Distributed
Mỗi service chạy process riêng (máy ảo/container) → tách rời triệt để, hết tranh chấp tài nguyên. Đổi lại: network call chậm hơn method call → hiệu năng là điểm yếu.
Bounded Context
Mỗi service mô hình một domain/subdomain; nội bộ gắn kết nhưng không ghép với schema/lớp của context khác.
Granularity
Hay mắc lỗi chia quá nhỏ rồi phải nối lại. Ba kim chỉ nam: Purpose (một trách nhiệm), Transactions (gom thực thể cần giao dịch chung), Choreography (gom nếu liên-service quá nhiều).
Data Isolation
Không DB/schema dùng chung làm điểm tích hợp. Mỗi đội tự chọn kho phù hợp nhất, đổi mà không ảnh hưởng đội khác.
03 Vận hành & giao tiếp
Tái sử dụng vận hành (không phải code)
Microservices tách domain khỏi vận hành: không tái dùng code nghiệp vụ, nhưng chia sẻ năng lực vận hành (logging, monitoring, circuit breaker) qua hạ tầng.
Sidecar
Tách phần vận hành chung thành một thành phần "đi kèm" trong mỗi service.
Service Mesh
Nối các sidecar thành một mặt phẳng điều khiển vận hành thống nhất toàn hệ.
Service Discovery
Request đi qua công cụ khám phá → tự tìm & bung thêm thực thể service khi cần. Thường đặt ở API layer.
API layer là proxy/điểm khám phá tuỳ chọn giữa người dùng & service — không được làm mediator hay chứa logic nghiệp vụ (khác hẳn ESB của SOA). Frontend: một UI khối (monolithic) gọi qua API, hoặc micro-frontend khớp ranh giới service để một đội làm trọn domain từ UI đến dữ liệu.
Giao tiếp giữa các service
Đồng bộ
REST/gRPC; service phải biết (hoặc khám phá) giao thức gọi nhau. Hỗ trợ polyglot — mỗi service một stack công nghệ khác nhau.
Bất đồng bộ
Dùng sự kiện/tin nhắn khi cần hiệu năng & quy mô; nhúng tinh thần Event-Driven (topic 09).
| Phối hợp | Choreography (biên đạo) | Orchestration (điều phối) |
|---|---|---|
| Cách làm | Service tự gọi nhau (như Broker, không nhạc trưởng) | Tạo một mediator cục bộ cho một workflow |
| Ưu | Giữ tách rời tối đa, nhanh, ít nút thắt | Dễ điều phối & xử lý lỗi cho luồng phức tạp |
| Nhược | Xử lý lỗi & điều phối phức tạp | Thêm chút ghép nối vào mediator |
Transactional Saga: thay vì giao dịch phân tán, dùng giao dịch bù (compensating) — mỗi bước có "do" & "undo" để hoàn tác khi lỗi. Nhưng undo phức tạp gấp bội → sách khuyên dùng saga thật tiết kiệm; lạm dụng giao dịch xuyên service là đi ngược lý do chọn microservices.
04 Đánh giá đặc tính — Microservices
Vô địch về mở rộng, đàn hồi, tiến hoá, mô-đun, linh hoạt (5★); triển khai & kiểm thử rất cao nhờ tự động hoá (4½★). Đổi lại 1★ chi phí & đơn giản — không có DevOps thì không tồn tại. (½ = nửa chấm)
05 Chọn phong cách phù hợp (Chương 18)
Không có phong cách "đúng" — chỉ có phong cách ít tệ nhất cho ngữ cảnh này. "Thời trang" kiến trúc luôn dịch chuyển theo hệ sinh thái (Docker, Kubernetes…), bài học quá khứ, năng lực mới. KTS quyết theo ba bước:
Monolith hay Distributed?
Dựa trên architecture quantum: một bộ đặc tính cho cả hệ → monolith; các phần cần đặc tính khác nhau → phân tán.
Dữ liệu sống ở đâu?
Monolith: một (vài) DB quan hệ. Phân tán: service nào sở hữu dữ liệu gì, và dữ liệu chảy thế nào qua các workflow.
Giao tiếp đồng bộ hay bất đồng bộ?
Mặc định đồng bộ (đơn giản, dễ debug); chỉ dùng bất đồng bộ khi cần hiệu năng/quy mô, chấp nhận rắc rối đồng bộ dữ liệu, deadlock, race.
Use synchronous by default, asynchronous when necessary. Đầu ra của quá trình này: topology + ADR (cho phần tốn công nhất) + fitness function (bảo vệ nguyên lý & đặc tính vận hành quan trọng).
Bản đồ chọn phong cách (tổng kết Phần II)
| Khi nhu cầu chính là… | Nghiêng về phong cách | Nhóm |
|---|---|---|
| Đơn giản, rẻ, nhỏ, đội chưa thuần Agile | Layered (06) | Monolith |
| Dòng xử lý dữ liệu tuần tự (ETL/EDI) | Pipeline (07) | Monolith |
| Sản phẩm nặng tùy biến / plug-in | Microkernel (07) | Monolith |
| Phân tán thực dụng: vài service + 1 DB | Service-Based (08) | Distributed |
| Throughput cao, phản ứng sự kiện, tách rời | Event-Driven (09) | Distributed |
| Mở rộng cực hạn, tải biến động khó lường | Space-Based (10) | Distributed |
| Agility, đội độc lập, tiến hoá nhanh, đặc tính khác nhau theo phần | Microservices (11) | Distributed |
Ví dụ · Silicon Sandwiches
Đơn giản, một quantum, ngân sách thấp → modular monolith (hoặc microkernel). Tách bảng theo domain để sau dễ "tách" thành phân tán nếu cần.
Ví dụ · Going, Going, Gone
Đấu giá: bidder / auctioneer / streamer cần đặc tính khác nhau, scale & performance cao → microservices (hợp hơn event-driven vì tách theo đặc tính vận hành).
RAG Chọn style cho hệ "Hỏi–đáp tài liệu": Một quantum hay nhiều? Với RAG nội bộ tải vừa, ingest & query có đặc tính khá khác (nền/đồng bộ) nhưng chưa tới mức cần đội độc lập → Service-Based thường "ít tệ nhất". Dữ liệu sống ở đâu: vector store là system of record. Giao tiếp: query đồng bộ (PHP↔Python) mặc định, ingest bất đồng bộ khi cần chịu tải. Chỉ leo lên Microservices khi nhiều đội, nhiều vendor model, và phần truy hồi cần scale độc lập với phần sinh câu trả lời.
06 Ghi nhớ nhanh
Microservices = bounded context + share nothing — fine-grained, database per service, ưa trùng lặp hơn ghép nối.
Tái dùng vận hành, không tái dùng code — sidecar + service mesh + service discovery; API layer là proxy, KHÔNG phải mediator.
Choreography mặc định, saga tiết kiệm — tránh giao dịch phân tán; lạm dụng là phản bội lý do chọn MSA.
Chọn style theo 3 bước — quantum (mono/distributed) → dữ liệu sống ở đâu → đồng bộ (mặc định) vs bất đồng bộ (khi cần).
"It depends" — luôn là đánh đổi — không nhắm phong cách tốt nhất, nhắm phong cách ít tệ nhất cho bài toán & ngữ cảnh hiện tại.