12 pattern · 4 nhóm · 1 quy tắc12 patterns · 4 groups · 1 rule

Mỗi lời gọi đồng bộ là một lần buộc chung số phận.Every synchronous call is a shared fate.

Microservices là một thương vụ mua bán, không phải một xu hướng. Đây là thứ bạn mua, thứ bạn trả, và mười hai chỗ hoá đơn thường đến sớm hơn dự tính.Microservices are a trade, not a trend. Here is what you buy, what you pay, and the twelve places the bill tends to arrive early.

Hoá đơnThe bill nét đứt = quyết định lúc chạydashed = decided at runtime
You buy independent deploy and team autonomy; you pay in consistency, latency and operations. BẠN MUA YOU BUY deploy độc lập independent deploy tự chủ của team team autonomy BẠN TRẢ YOU PAY tính nhất quán consistency độ trễ mạng network latency chi phí vận hành operational cost Nhóm 1–3 là thứ bạn mua. Nhóm 4 là lúc hoá đơn được gửi tới. Groups 1–3 are what you buy. Group 4 is when the invoice arrives.

Nếu bạn không thu được lợi ích, hãy ngừng trả giá.If you are not collecting the benefit, stop paying the price.

30s

Chọn cái nàoWhich one

phần dùng hằng ngày — tra cứu chi tiết ở dưới the daily-use part — detailed reference below

Thiết kế một lời gọi giữa hai serviceDesigning a call between two services

CÓ · YES
Có người đang chờ để quyết ngay → sync, kèm timeout + breaker + fallbackSomeone is waiting to decide now → sync, with timeout + breaker + fallback 04·07·08
KHÔNG · NO
Không ai chờ → async qua broker, kèm outbox + idempotency + DLQNobody is waiting → async via broker, with outbox + idempotency + DLQ 04·06

Định tách một service mớiAbout to split off a new service

KHÔNG · NO
Cùng tốc độ thay đổi, cùng chủ sở hữu → đừng chia, modular monolithSame change rate, same owner → do not split, modular monolith 12
KHÔNG · NO
Dữ liệu không tách rời được → chưa phải ranh giớiThe data will not split cleanly → not a boundary yet 01·02
CÓ · YES
Khác tốc độ, tách được dữ liệu → chia, rồi trả lời: undo thế nào?Different rates, data splits cleanly → split, then answer: how do you undo? 09

Sửa một hợp đồng API đang chạyChanging a live API contract

CÓ · YES
Không làm hỏng bên gọi cũ → cứ deploy, field mới phải optionalNo existing caller breaks → ship it, new fields must be optional 03
KHÔNG · NO
Có bên gọi hỏng → v2 song song + đo bên gọi + ngày khai tửA caller breaks → v2 in parallel + measure callers + a sunset date 03

Một service chậm đang kéo sập cả luồngOne slow service is taking down the flow

1 → 4
Đúng thứ tự này: timeout → bulkhead → breaker → fallbackIn this exact order: timeout → bulkhead → breaker → fallback 07·08
STOP
Chưa có trace-id xuyên chặng? Dừng mọi việc khác, làm tracing trước.No trace-id across hops? Stop everything else and do tracing first. 10
REF

Mười hai mụcThe twelve

màu = nhóm · quy ước ở cuối trang colour = group · legend at the foot of the page
NHÓM 01GROUP 01 Ranh giớiBoundaries Service bắt đầu và kết thúc ở đâu, ai sở hữu dữ liệu.Where a service starts and ends, and who owns the data.
01

Bounded ContextBounded Context

Cắt theo năng lực nghiệp vụ. Không bao giờ cắt theo tầng kỹ thuật.Split by business capability. Never by technical layer.

monolith orders payments shipping ✓ by business capability✗ by layer: ui · api · db
Dùng choUse for
Monolith có 3+ team giẫm chân nhau · một miền đổi hằng tuần, miền khác cả năm không đổi · chuẩn bị tách dần theo strangler figA monolith where 3+ teams collide · one domain changes weekly, another yearly · preparing a strangler-fig migration
ĐượcGain
Một tính năng = một PR, một lần deploy. Dev chỉ cần hiểu một mô hình.One feature = one PR, one deploy. A developer learns one model, not the system.
MấtCost
Khái niệm trùng lặp ở 3 nơi. Truy vấn xuyên context mất join. Vạch sai thì sửa rất đắt.Concepts duplicated in three places. Cross-context queries lose joins. A wrong line is expensive to move.

Dấu hiệu nhận biếtRecognition signalHai team cãi nhau xem “đơn hàng” nghĩa là gì — đó là hai context, không phải một cuộc tranh luận.Two teams arguing about what “order” means — that is two contexts, not a debate to settle.

02

Mỗi service một DBDB per Service

Không dùng chung database. API là con đường duy nhất đi vào.No shared database. The API is the only way in.

orders pay ship nobody reads another service's table
Dùng choUse for
Mỗi khi bạn tuyên bố một thứ là service · tách bảng nóng để scale riêng · cần công nghệ lưu trữ khác nhauAny time you claim something is a service · pulling a hot table out to scale it · needing different storage engines
ĐượcGain
Đổi schema không cần họp liên team. Một DB chết chỉ hỏng một chức năng.Schema changes need no cross-team meeting. One dead DB breaks one capability.
MấtCost
Mất join, mất ACID xuyên service, dữ liệu trùng và luôn trễ.No joins, no ACID across services, duplicated data that is always behind.

Dấu hiệu nhận biếtRecognition signalBạn không dám đổi tên một cột vì không biết ai đang đọc — database đang bị dùng chung.You dare not rename a column because someone might be reading it — the database is shared.

03

API có phiên bảnVersioned APIs

Chỉ thêm field, không bao giờ xoá. Bên gọi cũ vẫn phải chạy.Add fields, never remove them. Old callers must keep working.

idkept emailkept phone+ added name− removed add fields,never remove
Dùng choUse for
Từ bên tiêu thụ thứ hai trở đi · API cho đối tác · app mobile không cập nhật · event schema trong KafkaFrom the second consumer onward · partner APIs · mobile apps that never update · Kafka event schemas
ĐượcGain
Deploy độc lập thật sự an toàn. Canary khả thi vì hai version cùng chạy.Independent deploys become genuinely safe. Canary works because both versions run.
MấtCost
Hợp đồng tích tụ field chết. Hai version là gấp đôi test.The contract accumulates dead fields. Two versions means double the tests.

Dấu hiệu nhận biếtRecognition signalBạn phải nhắn “team A deploy trước rồi team B mới được deploy” — hợp đồng đang phá vỡ.You have to write “team A deploys first, then team B” — your contract is breaking.

NHÓM 02GROUP 02 Giao tiếpCommunication Các service nói chuyện thế nào, và vì sao mọi thông điệp đều đến hai lần.How services talk, and why every message arrives twice.
04

Đồng bộ / Bất đồng bộSync vs Async

Lời gọi thì ràng buộc. Event thì không.Calls couple. Events don’t.

a b sync · a waits, a is coupled a b async · a moves on
Dùng choUse for
Sync: xác thực, báo giá, kiểm tồn kho · Async: gửi email, đồng bộ CRM, fan-out, việc chạy dàiSync: auth, price quotes, stock checks · Async: email, CRM sync, fan-out, long-running work
ĐượcGain
B chết không kéo A xuống. Hàng đợi hấp thụ tải đột biến. Thêm consumer không cần sửa bên phát.B being down does not drag A down. The queue absorbs spikes. New consumers need no publisher change.
MấtCost
Nhất quán trễ rò rỉ lên UI. Chắc chắn có bản tin trùng và sai thứ tự. Phải vận hành broker.Eventual consistency leaks into the UI. Duplicates and reordering are guaranteed. You now run a broker.

Dấu hiệu nhận biếtRecognition signal“Bên kia chết thì request của tôi hỏng” — mà nghiệp vụ không cần trả lời ngay → phải là async.“If they’re down my request fails” — and the business does not need an immediate answer → make it async.

05

API GatewayAPI Gateway

Một cửa vào duy nhất, cho tất cả.One door in, for everyone.

web app gateway orders pay ship auth · routing · rate limits
Dùng choUse for
Nhiều loại client: web, mobile, đối tác · rate limit tại một chỗ · gắn trace-id cho mọi request vàoMultiple client types: web, mobile, partner · rate limiting in one place · attaching a trace-id at the edge
ĐượcGain
Bảo mật nhất quán, làm một lần. Client tách rời khỏi cách chia service bên trong.Consistent security, implemented once. Clients decoupled from the internal split.
MấtCost
Điểm chết đơn lẻ. Thêm một chặng mạng vào p99 của mọi request.A single point of failure. An extra hop on the p99 of every request.

Dấu hiệu nhận biếtRecognition signalMỗi lần tách service là app mobile phải cập nhật — bạn cần gateway.Every service split forces a mobile release — you need a gateway.

06

IdempotencyIdempotency

Cùng một thông điệp, hai lần, chỉ trừ tiền một lần.The same message, twice — one charge, not two.

key ab-91 charged key ab-91 same result one charge,not two
Dùng choUse for
Mọi thao tác trừ tiền, hoàn tiền · tạo đơn hàng · giữ và nhả tồn kho · mọi consumer đọc từ brokerEvery charge and refund · order creation · reserving and releasing stock · every broker consumer
ĐượcGain
Mở khoá retry an toàn — và chính nó mở khoá mục 07 và 08.Unlocks safe retries — which is what unlocks items 07 and 08.
MấtCost
Thêm một lượt ghi mỗi request. TTL và phạm vi key là quyết định thật, không thể qua loa.An extra write per request. TTL and key scope are real decisions, not defaults.

Dấu hiệu nhận biếtRecognition signalBạn không dám bật retry tự động vì sợ trừ tiền hai lần — bạn đang thiếu idempotency.You dare not enable retries in case it charges twice — you are missing idempotency.

NHÓM 03GROUP 03 Chịu lỗiFailure containment Mọi thứ ở đây sinh ra để sống sót qua sự ràng buộc của nhóm 2.Everything here exists to survive the coupling created in group 2.
07

TimeoutTimeouts

Fail nhanh, không bao giờ treo.Fail fast, never hang.

thread pool no timeout → whole pool hangs 1000800500300 budget shrinks down the chain (ms)
Dùng choUse for
Mọi lời gọi HTTP/gRPC · truy vấn database và cache · DNS · lấy kết nối từ poolEvery HTTP/gRPC call · database and cache queries · DNS · acquiring a pooled connection
ĐượcGain
p99 dự đoán được. Thread được nhả đúng lúc. Không có nó thì breaker không bao giờ kích hoạt.Predictable p99. Threads released on time. Without it a breaker never trips.
MấtCost
Quá chặt gây lỗi giả và bão retry. Cần số liệu p99 thật, đoán là sai.Too tight causes false failures and retry storms. Needs real p99 data; guessing fails.

Dấu hiệu nhận biếtRecognition signalDùng client mặc định của thư viện mà chưa từng đặt timeout — nhiều mặc định là vô hạn.Using the library default client with no timeout set — many defaults are infinite.

08

Circuit BreakerCircuit Breaker

Ngừng gọi một service đã chết.Stop calling a dead service.

5 / 5 failed in window OPEN stop calling for 30 sthen half-open probe your retries are their outage
Dùng choUse for
Gợi ý sản phẩm, làm giàu dữ liệu · tra cứu bên thứ ba có cache · thông báo đẩy vào hàng đợiRecommendations and enrichment · third-party lookups with a cached value · notifications queued for later
ĐượcGain
Chặn lỗi dây chuyền. Chừa khoảng lặng cho service phía dưới hồi phục.Stops cascading failure. Gives the downstream real idle time to recover.
MấtCost
Khó chỉnh ngưỡng, dễ ngắt oan. Vô dụng nếu không có fallback thiết kế sẵn.Hard to tune and trips on blips. Useless without a fallback designed in advance.

Dấu hiệu nhận biếtRecognition signalKhông viết nổi hàm fallback() — hãy thiết kế fallback trước khi bật breaker.You cannot write the fallback() function — design the fallback before enabling the breaker.

09

SagaSaga

Không có rollback, chỉ có hoàn tác. Và bạn tự viết phần đó.No rollback, only undo. And you write it yourself.

reserve✓ charge✓ ship✗ refund unreserve you write the undo yourself
Dùng choUse for
Thanh toán đơn · đặt vé, đặt phòng · mở tài khoản · hoàn tiềnCheckout · booking and reservations · account opening · refunds
ĐượcGain
Không cần khoá phân tán. Xem được đơn nào đang kẹt ở bước nào.No distributed locks. You can see which orders are stuck at which step.
MấtCost
Bạn tự test mọi nhánh hoàn tác. Có bước không hoàn tác được thật: email đã gửi.You test every undo path yourself. Some steps truly cannot be undone: the email was sent.

Dấu hiệu nhận biếtRecognition signalBạn định bọc BEGIN TRANSACTION quanh hai lời gọi HTTP — cái bạn cần là saga.You are about to wrap BEGIN TRANSACTION around two HTTP calls — what you need is a saga.

NHÓM 04GROUP 04 Vận hànhOperations Làm cho hệ phân tán nhìn thấy được — và nhận ra khi nó vốn không đáng.Making distribution visible — and noticing when it was never worth it.
10

TracingTracing

Một id duy nhất xuyên mọi chặng.One id across every hop.

trace-id 7f3a gateway orders payments shipping ← the cost
Dùng choUse for
Từ service thứ ba trở đi · điều tra sự cố · truy nguyên độ trễ · vẽ bản đồ phụ thuộc thậtFrom the third service onward · incident investigation · latency attribution · a real dependency map
ĐượcGain
Tìm nguyên nhân gốc từ hàng giờ xuống vài phút. Chấm dứt tranh cãi giữa các team.Root cause from hours to minutes. Ends inter-team arguments about whose fault it is.
MấtCost
Tốn công gắn ở mọi service. Chỉ một service làm rơi context là cả chuỗi gãy.Instrumentation effort everywhere. One service dropping context breaks the whole chain.

Dấu hiệu nhận biếtRecognition signalĐiều tra sự cố phải mở 5 tab Kibana và ghép tay theo timestamp — bạn thiếu tracing.Investigating means five Kibana tabs aligned by hand on timestamps — you are missing tracing.

11

Đọc nhất quán trễEventual Reads

Cái bạn vừa ghi, chưa thấy đâu.Your write, not there yet.

primary replica 40 ms behind stale read
Dùng choUse for
Bất kỳ hệ thống nào có read replica · CQRS · cache trước database · tìm kiếm ElasticsearchAny system with a read replica · CQRS · a cache in front of the DB · Elasticsearch search
ĐượcGain
Scale đọc rẻ hơn nhiều so với scale bản chính. Truy vấn nặng không làm chậm đường ghi.Read scaling far cheaper than scaling the primary. Heavy queries do not slow the write path.
MấtCost
Dữ liệu cũ hiện ra đúng lúc user chú ý nhất. Bug ma không tái hiện được ở máy local.Stale data appears exactly when the user is watching. Ghost bugs never reproduce locally.

Dấu hiệu nhận biếtRecognition signalVé lỗi kiểu “tôi lưu rồi mà không thấy, lát sau vào lại thì thấy” — là replica lag chưa xử lý.Tickets saying “I saved it and it wasn’t there, then later it was” — unhandled replica lag.

12

Cái bẫyThe Trap

Monolith phân tán. Tệ hơn cả monolith bạn bắt đầu.A distributed monolith. Worse than the one you started with.

a b c d sync, all of them
Dùng choUse for
Chạy bài kiểm tra trước khi tách thêm service · khi vận tốc release chậm dần · review kiến trúc hằng quýRun the test before splitting again · when release velocity slows · at the quarterly architecture review
ĐượcGain
Thừa nhận sớm thì vẫn quay lại được: gộp service tốn vài tuần, không phải vài năm.Admit it early and you can still go back: merging takes weeks, not years.
MấtCost
Trả đủ hoá đơn — độ trễ, lỗi cục bộ, chi phí vận hành — mà không thu lại được gì.You pay the full bill — latency, partial failure, ops cost — and collect nothing.

Dấu hiệu nhận biếtRecognition signalKhông ai dám trả lời “hôm nay service X deploy một mình được không?” bằng chữ có.Nobody will answer “can service X ship alone today?” with yes.

$$

Bảng đánh đổiTrade-off table

# Pattern Chi phí làmCost to build Độ trễ thêmAdded latency Lợi ích tin cậyReliability payoff Khó vận hànhOps difficulty Bắt buộc?Mandatory?
01Bounded ContextCao (phân tích)High (analysis)00Gián tiếp, rất lớnIndirect, very largeThấpLowCóYes
02DB per ServiceCao (di dời dữ liệu)High (data migration)+1 hop+1 hopCaoHighTrung bìnhMediumCóYes
03Versioned APIsThấpLow00CaoHighThấpLowCóYes
04Async / OutboxTrung bìnhMedium+ độ trễ hàng đợi+ queue delayRất caoVery highCaoHighTuỳ chỗSituational
05API GatewayThấp (mua sẵn)Low (buy it)+1–5ms+1–5msTrung bình, kèm SPOFMedium, adds a SPOFTrung bìnhMediumTừ 2 clientFrom 2 clients
06IdempotencyThấpLow+1 lượt ghi+1 writeRất caoVery highThấpLowCóYes
07Timeout + BulkheadRất thấpVery low00Rất caoVery highThấpLowCóYes
08Circuit BreakerTrung bìnhMedium− nhanh hơn khi lỗi− faster on failureCaoHighTrung bìnhMediumNên cóRecommended
09SagaRất caoVery high+ nhiều bước+ multiple stepsCaoHighCaoHighKhi có luồng đa serviceFor multi-service flows
10TracingTrung bìnhMedium+ ~1%+ ~1%Gián tiếp, rất lớnIndirect, very largeTrung bìnhMediumTừ 3 serviceFrom 3 services
11Xử lý read lagLow–MedLow–Med+0–50ms+0–50msTrung bìnhMediumThấpLowKhi có replicaWith any replica
12Coupling testRất thấpVery low00Gián tiếpIndirectRất thấpVery lowCóYes

Đọc bảng này thế nào: rẻ nhất và lợi nhất là 07 · 06 · 03 — làm trước. Đắt nhất là 09 · 02 · 01 — chỉ làm khi trả lời được vì sao. Mục 12 gần như miễn phí, chạy hằng quý. How to read this: cheapest and highest payoff are 07 · 06 · 03 — do those first. Most expensive are 09 · 02 · 01 — only once you can explain why. Item 12 costs almost nothing; run it quarterly.

✗

Anti-patterns

Sai lầmMistake Vì sao saiWhy it is wrong Sửa thế nàoHow to fix it
Chia service theo tầng (ui-svc, api-svc, db-svc)Splitting by layer (ui-svc, api-svc, db-svc)Mọi thay đổi nghiệp vụ đụng cả ba → deploy đồng loạtEvery business change touches all three → coordinated deployCắt lại theo năng lực nghiệp vụ (01)Re-cut along business capability (01)
“Chỉ đọc thôi” vào DB của service khác“Read-only access” into another service’s DBBên đọc phụ thuộc tên cột; schema của bạn đóng băngThe reader depends on your column names; your schema freezesAPI hoặc read model dựng từ event (02)An API or an event-fed read model (02)
Retry mà không có idempotencyRetries without idempotencyTrừ tiền hai lần, tạo đơn trùngDouble charges, duplicate ordersIdempotency key + unique index (06)Idempotency key + unique index (06)
Dùng timeout mặc định của thư việnUsing the library’s default timeoutMặc định của nhiều client là vô hạnMany client defaults are infiniteĐặt từ p99, truyền deadline tuyệt đối (07)Set from p99, propagate an absolute deadline (07)
Timeout tầng trong lớn hơn tầng ngoàiInner timeout larger than the outer oneBên ngoài bỏ cuộc, bên trong vẫn giữ tài nguyênThe caller gave up; the inner call still holds resourcesNgân sách nhỏ dần theo chuỗi (07)Budget shrinks down the chain (07)
Circuit breaker không có fallbackA circuit breaker with no fallbackChỉ đổi lỗi chậm thành lỗi nhanhIt only converts a slow failure into a fast oneThiết kế fallback trước khi bật (08)Design the fallback before enabling it (08)
Ngắt breaker theo số đếm thay vì tỷ lệTripping the breaker on a count, not a rateLúc lưu lượng thấp sẽ mở oanIt opens for no reason during low trafficTỷ lệ lỗi + số mẫu tối thiểu (08)Error rate + a minimum sample size (08)
2PC / distributed transaction giữa các service2PC / distributed transactions across servicesKhoá phân tán, không sống nổi khi mạng chập chờnDistributed locks; does not survive a flaky networkSaga + bù trừ nghiệp vụ (09)A saga with business compensation (09)
Bước không hoàn tác được nằm giữa sagaAn irreversible step in the middle of a sagaKhông có cách nào quay lạiThere is no way backSắp nó xuống cuối cùng (09)Move it to the end (09)
Log tập trung nhưng không có trace idCentralized logs with no trace idCó log của mọi service, không có chuỗi nhân quảLogs from every service, no causal chainOpenTelemetry + traceparent (10)OpenTelemetry + traceparent (10)
Quên truyền trace context qua message asyncForgetting trace context on async messagesChuỗi trace gãy đúng chỗ khó debug nhấtThe trace breaks exactly where debugging is hardestInject context vào header của message (10)Inject the context into message headers (10)
Logic nghiệp vụ nằm trong gatewayBusiness logic inside the gatewayMọi thay đổi nghiệp vụ phải deploy gatewayEvery business change requires a gateway deployGateway chỉ định tuyến + chính sách (05)The gateway does routing and policy only (05)
Ghi xong đọc lại ngay từ replicaReading from a replica right after writingTrả về dữ liệu cũ, trông như ghi thất bạiReturns stale data; it looks like the write failedSticky primary hoặc render từ response (11)Sticky primary, or render from the response (11)
Chia microservices khi team có 4 ngườiAdopting microservices with a team of fourChi phí phối hợp lớn hơn lợi ích tự chủCoordination cost exceeds the autonomy benefitModular monolith (12)Modular monolith (12)
Chia thêm service để chữa hệ thống đang rốiSplitting more services to fix a messy systemThêm ranh giới mạng lên một mô hình đã saiAdds network boundaries on top of a wrong modelSửa ranh giới trước, hoặc gộp lại (12)Fix the boundaries first, or merge back (12)
03

Ba câu cần nhớThree things to remember

01

Mỗi lời gọi đồng bộ là một lần buộc chung số phận.

Every synchronous call is a shared fate.

Trước khi thêm một lời gọi, hãy hỏi: bên kia chết thì request này ra sao? Before adding one, ask: what happens to this request when the other side is down?
02

Bạn mua deploy độc lập và tự chủ của team. Bạn trả bằng nhất quán, độ trễ, vận hành.

You buy independent deployment and team autonomy. You pay in consistency, latency and operations.

Toàn bộ thương vụ chỉ có vậy — không có phần thưởng ẩn nào khác. That is the entire deal — there is no hidden bonus round.
03

Nếu không thu được lợi ích, hãy ngừng trả giá.

If you are not collecting the benefit, stop paying the price.

Gộp service lại là một nước đi kỹ thuật hợp lệ, không phải lời thú nhận thất bại. Merging services back is a legitimate engineering move, not an admission of failure.