API Gateway
API gateway là cửa vào duy nhất cho client: định tuyến, xác thực, rate limit, gộp response và kết thúc TLS. Bài này phân biệt gateway với load balancer và service mesh, giải thích pattern BFF, so sánh Kong, Envoy, AWS API Gateway, Nginx và cách tính overhead, sizing.
API gateway là gì và mô hình cốt lõi
Khi hệ thống có nhiều service, client (web, mobile, đối tác) không nên biết địa chỉ của từng service. API gateway là một service đứng trước tất cả, làm điểm vào duy nhất cho mọi request từ bên ngoài, rồi chuyển tới đúng service phía sau. Microservices Patterns ch.8 mô tả nó tương tự pattern Facade trong lập trình hướng đối tượng: nó che kiến trúc bên trong và cung cấp API cho client.1
Các trách nhiệm điển hình theo sách: định tuyến request, gộp response (API composition), chuyển đổi giao thức, cung cấp API riêng cho từng loại client, và các "edge function" như xác thực, phân quyền, rate limit, cache, thu thập metrics, ghi log request.1 Kết thúc TLS cũng là việc thường làm ở tầng proxy L7 này.2
| Trách nhiệm | Ví dụ |
|---|---|
| Routing | /orders/* tới order-service, /users/* tới user-service |
| Kết thúc TLS | Giải mã HTTPS ở gateway, nội bộ dùng HTTP hoặc mTLS |
| Xác thực | Kiểm tra JWT, API key; gắn token hoặc x-user-id cho service sau |
| Rate limit, quota | Ví dụ (giả định): 100 request/phút mỗi user, 10.000/ngày mỗi API key đối tác |
| Gộp response (aggregation) | Một request /home gọi song song 4 service rồi gộp |
| Chuyển đổi giao thức | REST bên ngoài, gRPC bên trong; WebSocket tới service realtime |
| Quan sát | Access log, metrics theo route, gắn trace id |
| Chính sách khác | CORS, nén, cache response, request size limit, canary theo header |
Gateway giúp gom các mối quan tâm chung về một chỗ, nên service phía sau chỉ lo nghiệp vụ, và client chỉ cần một round trip thay vì gọi nhiều service. Mặt trái: nó là thêm một thành phần cần sẵn sàng cao phải phát triển, deploy và vận hành, và có thể thành nút thắt phát triển khi mọi đội đều phải sửa nó.3 Nếu nhồi quá nhiều logic nghiệp vụ vào lớp gộp này, nó thành một lớp dày mà chức năng nào đổi cũng phải sửa theo.4
Kiến trúc
Gateway chạy nhiều instance phía sau một load balancer; một instance chết thì load balancer chuyển request sang instance khác.5 Trạng thái cần chia sẻ như bộ đếm rate limit nằm ở một database tập trung, Grokking gợi ý Redis hoặc Cassandra, đổi lại thêm độ trễ khi lưu lượng lớn.6 Xem thêm Redis. Cấu hình route có thể là module định tuyến đọc file cấu hình mô tả luật routing; quy trình deploy gateway cần tự động hoàn toàn để các đội không phải chờ nhau.1
Xác thực ở gateway: client gửi credentials, gateway xác thực rồi chuyển một token (ví dụ JWT chứa danh tính và vai trò) tới các service, để service biết ai đang gọi.7
Gateway, load balancer và service mesh
Ba thứ này hay bị lẫn vì đều là proxy:
| Load balancer | API gateway | Service mesh | |
|---|---|---|---|
| Vị trí | Trước một nhóm server giống nhau | Biên hệ thống, giữa client và nhiều service | Giữa các service nội bộ (east-west) |
| Hiểu biết | L4 (TCP/UDP) hoặc L7 (header, URL, cookie) | L7 sâu: user, API key, payload, phiên bản API | L7 cho lưu lượng nội bộ |
| Chức năng chính | Chia tải, health check, kết thúc TLS | Auth, rate limit, routing theo API, aggregation | TLS giữa service, circuit breaker, tracing, service discovery, routing |
| Ví dụ | AWS ALB/NLB, HAProxy | Kong, AWS API Gateway, Apigee, Envoy Gateway | Istio, Linkerd, Cilium |
Grokking ch.8 phân biệt L4 (theo TCP/UDP, xử lý nhanh hơn) và L7 (quyết định theo HTTP header, URL, cookie, user ID; có thể làm rate limit, routing HTTP, sửa header).2 Microservices Patterns mô tả service mesh là tầng mạng trung gian cho mọi lưu lượng vào ra service, lo circuit breaker, tracing, service discovery, load balancing, routing theo luật và TLS giữa các service.8 Cột "Ví dụ" là tên sản phẩm, chưa có sách trong thư viện so sánh chúng.9
Trong thực tế chúng chồng lên nhau: cùng một proxy có thể vừa là load balancer, gateway và sidecar của mesh.9 Câu trả lời tốt trong phỏng vấn là mô tả lưu lượng: north-south (từ ngoài vào) đi qua gateway, east-west (service gọi service) do mesh hoặc thư viện client lo.8
BFF và gộp response
Mỗi loại client cần dữ liệu khác nhau. Màn hình chi tiết sản phẩm trên mobile cần gọn, trên web cần đầy đủ, API đối tác cần ổn định lâu dài. Một gateway chung cho tất cả sẽ phình to và trách nhiệm bị mờ khi nhiều đội cùng sửa một code base.10
Pattern Backends for Frontends (BFF) tách mỗi loại client một gateway riêng, do chính đội client đó sở hữu và vận hành.104 Lợi ích thêm theo Microservices Patterns: các API cô lập nhau nên một API hỏng khó ảnh hưởng API khác, dễ quan sát hơn, và mỗi API scale độc lập. Phần dùng chung (edge function như xác thực) nằm trong một thư viện chung do đội gateway giữ.10 Building Microservices nhấn mạnh BFF chỉ nên chứa hành vi riêng cho trải nghiệm của client đó, logic nghiệp vụ phải ở lại trong service; lớp xác thực có thể đặt giữa UI và các BFF.4
Ví dụ BFF mobile viết bằng Node.js, gộp ba service song song và chịu lỗi từng phần:
app.get("/m/products/:id", async (req, res) => {
const id = req.params.id;
const [product, reviews, stock] = await Promise.allSettled([
catalog.get(`/products/${id}`, { timeout: 300 }),
review.get(`/products/${id}/summary`, { timeout: 200 }),
inventory.get(`/stock/${id}`, { timeout: 200 }),
]);
if (product.status === "rejected") return res.status(502).end();
res.json({
...pickMobileFields(product.value),
rating: reviews.status === "fulfilled" ? reviews.value.avg : null,
inStock: stock.status === "fulfilled" ? stock.value.qty > 0 : undefined,
});
});
Điểm cần chú ý: gọi song song, timeout cho từng service, và trả kết quả một phần khi service phụ lỗi. Gọi tuần tự thì thời gian phản hồi là tổng thời gian các service; gọi song song thì xấp xỉ bằng service chậm nhất. Với Node.js, promise là cách viết code song song dễ đọc thay cho callback.5 Microservices Patterns cũng nêu đúng cách xử lý lỗi này: dữ liệu thiết yếu (sản phẩm) không có thì trả lỗi hoặc bản cache, dữ liệu phụ (đánh giá, tồn kho) không có thì vẫn trả phần còn lại.11 GraphQL là một cách khác để làm tầng gộp này, client tự chọn field cần lấy.12
Sai lầm hay gặp: Gọi tuần tự 5 service trong gateway, mỗi cái 40 ms, thành 200 ms. Hoặc không đặt timeout, một service treo giữ chặt tài nguyên (thread, connection) và cuối cùng gateway không nhận thêm được request nào.513
Lựa chọn sản phẩm
Microservices Patterns chia hai hướng: dùng sản phẩm hoặc dịch vụ gateway có sẵn (ít phải code nhưng kém linh hoạt, thường không hỗ trợ API composition), hoặc tự viết gateway trên một framework web (linh hoạt nhất nhưng tốn công).14
| Sản phẩm | Kiểu | Điểm mạnh | Lưu ý |
|---|---|---|---|
| Nginx / OpenResty | Reverse proxy tự cấu hình | Định tuyến kiểu reverse proxy, quen thuộc | Auth, rate limit nâng cao phải viết thêm |
| Kong | Gateway trên nền NGINX | Luật routing theo method, header, path; plugin cho edge function như xác thực | Tự cài đặt và vận hành; không có API composition |
| Envoy (Envoy Gateway, Contour, Istio ingress) | Proxy hiện đại | HTTP/2, gRPC, cấu hình động | Cấu hình phức tạp nếu dùng trực tiếp |
| AWS API Gateway | Managed | Không phải cài đặt, vận hành hay tự scale; tích hợp Lambda; xác thực request | Không hỗ trợ API composition |
| Cloud khác | GCP API Gateway, Apigee, Azure APIM | Quản lý API đối tác, developer portal | Phù hợp doanh nghiệp |
| Tự viết bằng Node.js | Express, Fastify | Linh hoạt cho BFF và aggregation | Phải tự lo routing, hiệu năng, bảo mật |
Các dòng Nginx, Kong, AWS API Gateway và "tự viết" theo Microservices Patterns ch.8.114 Các dòng Envoy và "Cloud khác" là kiến thức sản phẩm chưa có sách trong thư viện.9
Cách phổ biến: một proxy hoặc gateway có sẵn làm edge cho routing và edge function, và BFF tự viết (ví dụ bằng Node.js) cho logic gộp theo từng client, vì sản phẩm có sẵn thường không làm API composition.14
Overhead, capacity và sizing
Các con số dưới đây là ước lượng. Mốc từ sách: một round trip trong cùng datacenter khoảng 500 µs, và một cache server xử lý cỡ 100.000 tới 1 triệu QPS.15 Các con số còn lại là giả định của khoá học, cần load test.
| Chỉ số | Ước lượng |
|---|---|
| Độ trễ thêm của một proxy cùng DC | Ít nhất một round trip (~0,5 ms), thêm thời gian xử lý nếu có plugin nặng |
| Kiểm tra JWT tại chỗ (cache public key) | Không cần gọi mạng; giả định dưới 1 ms |
| Gọi auth service mỗi request | Thêm một round trip; nên cache kết quả một thời gian ngắn |
| Rate limit qua Redis | Thêm một round trip tới Redis mỗi request |
| Envoy / Nginx, 2 vCPU | Giả định ~8.000 request/s cho request nhỏ, cần load test |
| BFF Node.js I/O-bound | ~500 req/s mỗi vCPU; 2 vCPU · 4 GB ≈ 1.000 req/s (quy tắc ước lượng của khoá học, xem chọn server) |
Gateway dùng I/O bất đồng bộ (non-blocking) scale tốt hơn mô hình một thread mỗi kết nối, vì không tốn chi phí cho nhiều thread. Sách ghi lại kinh nghiệm Netflix: chuyển gateway sang non-blocking giúp tăng thông lượng cho logic nặng I/O như routing, nhưng không cải thiện cho logic nặng CPU như giải mã, nén.5
Ví dụ (giả định): peak 30.000 request/s vào edge, 40% đi qua BFF mobile.
Edge gateway, mỗi instance 2 vCPU ~8.000 req/s (giả định), chạy ≤ 60%
→ 30.000 / (8.000 × 0,6) ≈ 6,25 → 7 instance, tối thiểu 2 mỗi zone
BFF mobile: 12.000 req/s
→ instances = max(2, ceil(12.000 / 600)) = 20 instance 2 vCPU · 4 GB
Redis rate limit: 30.000 ops/s → dưới mức một cache server, một node + replica là đủ
Ngưỡng 60% CPU và 600 req/s mỗi instance là quy tắc ước lượng của khoá học.16 Mức Redis đối chiếu với con số cache server ở trên.15
Managed gateway tính tiền theo request, nên khi lưu lượng lớn hóa đơn có thể vượt xa chi phí tự chạy proxy trên vài máy. Hãy tính theo bảng giá hiện tại trước khi chọn. Managed gateway hợp với lưu lượng thấp hoặc vừa.9
Mẹo: Luôn đặt timeout cho mọi lời gọi ra ngoài process và chọn một giá trị mặc định cho tất cả, ghi log khi timeout xảy ra để chỉnh.13 Đặt timeout ở gateway nhỏ hơn timeout của client, bật connection pooling và keep-alive tới upstream để không mở kết nối TCP mới cho mỗi request (gợi ý của khoá học).
Khi nào dùng và khi nào không
Theo Microservices Patterns, với đa số ứng dụng thực tế dùng API gateway là hợp lý; nếu cần thì dùng BFF để các đội phát triển và deploy API độc lập.3
| Tình huống | Gợi ý |
|---|---|
| Monolith, một client web | Load balancer cộng middleware trong app là đủ |
| Vài service, một đội | Một gateway đơn giản (Nginx, Kong, hoặc cloud) cho routing, TLS, auth |
| Nhiều client khác nhau, nhiều đội | Edge gateway cộng BFF cho từng client |
| API công khai cho đối tác, cần API key, quota, portal | Gateway có sẵn hoặc managed có quản lý API key và quota |
| Nhiều service gọi nhau, cần TLS và circuit breaker thống nhất | Service mesh cho east-west, gateway vẫn ở biên |
| WebSocket hoặc streaming lâu | Gateway hỗ trợ upgrade, hoặc route thẳng tới WebSocket gateway riêng |
Không nên đặt vào gateway hoặc BFF: logic nghiệp vụ, transaction, truy vấn database trực tiếp.4 Cũng không nên cho file lớn đi qua gateway: để client upload thẳng lên object storage bằng presigned URL, xem file lớn.
Vận hành ở quy mô nhỏ và lớn
Nhỏ. Dùng ingress có sẵn của nền tảng: load balancer cloud cộng một middleware auth trong app, hoặc managed API gateway nếu dùng serverless. Dịch vụ managed lo cài đặt, vận hành và scale.14
Vừa. Một gateway tự vận hành trên Kubernetes, cấu hình route bằng file trong git, review như code, pipeline deploy tự động.1 Chạy nhiều instance sau load balancer, ít nhất 2 mỗi availability zone.5 Theo dõi theo từng route: request rate, tỷ lệ lỗi 4xx/5xx, p50/p95/p99, số kết nối upstream, số request bị rate limit.
Lớn. Chia gateway theo miền (public API, mobile, internal admin) để một sự cố không làm sập toàn bộ, cùng lý do BFF cô lập các API.10 Triển khai cấu hình theo canary. Kết hợp CDN và WAF phía trước để chặn bot và DoS trước khi tới gateway; load balancer cũng có thể giảm nhẹ tấn công DoS ở nhiều tầng.2 Gateway đa region dùng global server load balancing qua DNS hoặc anycast.17
Sự cố hay gặp: một thay đổi cấu hình route sai làm hỏng mọi API; gateway hết tài nguyên vì upstream chậm mà không có timeout hay circuit breaker;5 rate limit dùng Redis mà Redis chết thì nên fail-open hay fail-closed. Grokking chọn mặc định không chặn request khi rate limiter lỗi, vì còn các lớp rate limit khác và load balancer.18 Với endpoint nhạy cảm như đăng nhập, khoá học gợi ý cân nhắc fail-closed (giả định của khoá học).
Điểm nói trong phỏng vấn
- Vẽ gateway ở biên, nói rõ nó làm gì: TLS, auth JWT, rate limit, routing.1 Không cần đi sâu nếu đề bài không xoay quanh nó.
- Phân biệt north-south (gateway) và east-west (mesh hoặc gọi trực tiếp).8
- Nhắc BFF khi đề bài có cả web và mobile với nhu cầu khác nhau, ví dụ news feed, Instagram, YouTube.10
- Rate limit ở gateway là chỗ tự nhiên cho bài rate limiter, vì mọi lưu lượng đều đi qua API endpoint;6 auth ở gateway giúp service phía sau tin tưởng token chứa user id.7
- Đưa con số: proxy thêm ít nhất một round trip, BFF gọi song song, timeout từng service.155
- Liên hệ thiết kế API cho versioning và mạng cơ bản cho L4/L7.
Trong phỏng vấn: "Client đi qua CDN, rồi API gateway kiểm JWT và rate limit bằng Redis, route tới BFF mobile; BFF gọi song song catalog, review, inventory với timeout 200–300 ms và trả kết quả một phần nếu service phụ lỗi." Một câu như vậy đủ cho phần biên của hầu hết các bài.
Nguồn trích dẫn
-
Microservices Patterns (file .zip, tải về giải nén) · ch.8 · §8.2 The API gateway pattern, §8.2.1 Overview of the API gateway pattern, các mục "Request routing", "API composition", "Protocol translation", "Implementing edge functions", "API gateway architecture", "API gateway ownership model" (tr. 259–264). ↩ ↩2 ↩3 ↩4 ↩5 ↩6
-
Grokking Modern System Design · ch.8 Load Balancers · mục "Services offered by load balancers" và "Types of load balancers". ↩ ↩2 ↩3
-
Microservices Patterns (file .zip, tải về giải nén) · ch.8 · §8.2.2 Benefits and drawbacks of an API gateway (tr. 267). ↩ ↩2
-
Building Microservices (file .zip, tải về giải nén) · ch.4 Integration · mục "Backends for Frontends" (tr. 71–72). ↩ ↩2 ↩3 ↩4
-
Microservices Patterns (file .zip, tải về giải nén) · ch.8 · §8.2.4 API gateway design issues, các mục "Performance and scalability", "Use reactive programming abstractions", "Handling partial failures" (tr. 268–270). ↩ ↩2 ↩3 ↩4 ↩5 ↩6 ↩7
-
Grokking Modern System Design · ch.19 Rate Limiter · mục "Where to place the rate limiter" và "Two models for implementing a rate limiter". ↩ ↩2
-
Microservices Patterns (file .zip, tải về giải nén) · ch.11 · §11.1.2 Implementing security in a microservice architecture, pattern Access token và mục "Using JWTs to pass user identity and roles" (tr. 354–357). ↩ ↩2
-
Microservices Patterns (file .zip, tải về giải nén) · ch.11 · §11.4.2 From microservice chassis to service mesh (tr. 380–381). ↩ ↩2 ↩3
-
Chưa có nguồn trong thư viện: thư viện không có sách về Envoy, Istio, Apigee hay bảng giá gateway cloud; chỉ nêu tên và đặc điểm chung, không đưa số liệu sản phẩm. ↩ ↩2 ↩3 ↩4
-
Microservices Patterns (file .zip, tải về giải nén) · ch.8 · §8.2.1, mục "Using the Backends for frontends pattern" (tr. 264–266). ↩ ↩2 ↩3 ↩4 ↩5
-
Microservices Patterns (file .zip, tải về giải nén) · ch.3 · §3.2.3 Handling partial failure using the Circuit breaker pattern, mục "Recovering from an unavailable service" (tr. 77–80). ↩
-
Microservices Patterns (file .zip, tải về giải nén) · ch.8 · §8.3.3 Implementing an API gateway using GraphQL. ↩
-
Building Microservices (file .zip, tải về giải nén) · ch.11 Microservices at Scale · mục "Timeouts" (tr. 211) và "Circuit Breakers" (tr. 212). ↩ ↩2
-
Microservices Patterns (file .zip, tải về giải nén) · ch.8 · §8.3 Implementing an API gateway, §8.3.1 Using an off-the-shelf API gateway product/service (tr. 271–272). ↩ ↩2 ↩3 ↩4
-
Grokking Modern System Design · ch.5 Back-of-the-envelope Calculations · mục "Standard numbers to remember" (bảng Important Latencies và Important Rates). ↩ ↩2 ↩3
-
Quy tắc ước lượng của khoá học (500 req/s mỗi vCPU, chạy tối đa 60% CPU), xem bài Chọn server. ↩
-
Grokking Modern System Design · ch.8 Load Balancers · mục "Global server load balancing" và "Load balancing in DNS". ↩
-
Grokking Modern System Design · ch.19 Rate Limiter · Detailed design, mục "Request processing" (Point to Ponder về rate limiter bị lỗi). ↩