Harbor

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.

14 phút đọcCông nghệ chủ chốt

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ệmVí dụ
Routing/orders/* tới order-service, /users/* tới user-service
Kết thúc TLSGiải mã HTTPS ở gateway, nội bộ dùng HTTP hoặc mTLS
Xác thựcKiểm tra JWT, API key; gắn token hoặc x-user-id cho service sau
Rate limit, quotaVí 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ứcREST bên ngoài, gRPC bên trong; WebSocket tới service realtime
Quan sátAccess log, metrics theo route, gắn trace id
Chính sách khácCORS, 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

Đang vẽ sơ đồ…

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 balancerAPI gatewayService mesh
Vị tríTrước một nhóm server giống nhauBiên hệ thống, giữa client và nhiều serviceGiữa các service nội bộ (east-west)
Hiểu biếtL4 (TCP/UDP) hoặc L7 (header, URL, cookie)L7 sâu: user, API key, payload, phiên bản APIL7 cho lưu lượng nội bộ
Chức năng chínhChia tải, health check, kết thúc TLSAuth, rate limit, routing theo API, aggregationTLS giữa service, circuit breaker, tracing, service discovery, routing
Ví dụAWS ALB/NLB, HAProxyKong, AWS API Gateway, Apigee, Envoy GatewayIstio, 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

Đang vẽ sơ đồ…

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ẩmKiểuĐiểm mạnhLưu ý
Nginx / OpenRestyReverse proxy tự cấu hìnhĐịnh tuyến kiểu reverse proxy, quen thuộcAuth, rate limit nâng cao phải viết thêm
KongGateway trên nền NGINXLuật routing theo method, header, path; plugin cho edge function như xác thựcTự cài đặt và vận hành; không có API composition
Envoy (Envoy Gateway, Contour, Istio ingress)Proxy hiện đạiHTTP/2, gRPC, cấu hình độngCấu hình phức tạp nếu dùng trực tiếp
AWS API GatewayManagedKhông phải cài đặt, vận hành hay tự scale; tích hợp Lambda; xác thực requestKhông hỗ trợ API composition
Cloud khácGCP API Gateway, Apigee, Azure APIMQuản lý API đối tác, developer portalPhù hợp doanh nghiệp
Tự viết bằng Node.jsExpress, FastifyLinh hoạt cho BFF và aggregationPhả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 requestThêm một round trip; nên cache kết quả một thời gian ngắn
Rate limit qua RedisThêm một round trip tới Redis mỗi request
Envoy / Nginx, 2 vCPUGiả đị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ốngGợi ý
Monolith, một client webLoad balancer cộng middleware trong app là đủ
Vài service, một độiMột gateway đơn giản (Nginx, Kong, hoặc cloud) cho routing, TLS, auth
Nhiều client khác nhau, nhiều độiEdge gateway cộng BFF cho từng client
API công khai cho đối tác, cần API key, quota, portalGateway 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ấtService mesh cho east-west, gateway vẫn ở biên
WebSocket hoặc streaming lâuGateway 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

  1. 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

  2. Grokking Modern System Design · ch.8 Load Balancers · mục "Services offered by load balancers" và "Types of load balancers". ↩ ↩2 ↩3

  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

  4. 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

  5. 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

  6. 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

  7. 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

  8. 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

  9. 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

  10. 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

  11. 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). ↩

  12. Microservices Patterns (file .zip, tải về giải nén) · ch.8 · §8.3.3 Implementing an API gateway using GraphQL. ↩

  13. 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

  14. 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

  15. 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

  16. 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. ↩

  17. Grokking Modern System Design · ch.8 Load Balancers · mục "Global server load balancing" và "Load balancing in DNS". ↩

  18. Grokking Modern System Design · ch.19 Rate Limiter · Detailed design, mục "Request processing" (Point to Ponder về rate limiter bị lỗi). ↩