[Microservices Series] Bài 7: API Gateway – "Người gác cổng vĩ đại" che chắn mớ hỗn độn
Chào anh em! Ở bài 6, chúng ta đã trang bị Circuit Breaker để bảo vệ các service không bị "cắn xé" lẫn nhau khi có sự cố nội bộ. Nhưng đó là chuyện trong nhà. Còn đối với thế giới bên ngoài (Mobile App, Web Application, hay hệ thống của đối tác), nếu chúng ta phơi bày hàng chục cái microservices ra trước gió thì chẳng khác nào "mở cửa rước trộm".
Hãy tưởng tượng một kịch bản tồi tệ: Ứng dụng di động của bạn cần hiển thị màn hình Home. Để có dữ liệu, Mobile Dev phải viết code gọi API tới IP của Service User (lấy tên), gọi sang IP của Service Wallet (lấy số dư), rồi lại gọi sang IP của Service Ticket (lấy lịch sử đi lại). Điều gì xảy ra?
-
Frontend cực khổ: Quản lý hàng tá URL, IP khác nhau. Lỡ một service đổi IP hay đổi port là Frontend phải update app hộc máu.
-
Bảo mật toang hoác: Các service nội bộ bị phơi IP public ra internet. Hacker tha hồ DDOS thẳng vào cái service yếu nhất.
-
Phân mảnh xác thực: Service nào cũng phải tự viết một đoạn code để check xem JWT Token có hợp lệ không.
Đó là lúc chúng ta cần một API Gateway.
API Gateway thực chất làm nhiệm vụ gì?
Nói nôm na, API Gateway giống như ông bảo vệ kiêm lễ tân ở sảnh của một tòa nhà văn phòng. Bất kỳ ai muốn vào tòa nhà đều phải gặp ông này trước.
1. Routing (Định tuyến và Ẩn danh) Client bên ngoài chỉ cần biết duy nhất một địa chỉ (ví dụ: api.metro.vn). Khi request đập vào Gateway:
-
Nếu đường dẫn là
/api/users/..., Gateway tự động forward (Reverse Proxy) request đó vào mớ IP nội bộ của Service User. -
Nếu là
/api/tickets/..., nó forward qua Service Ticket. Nhờ vậy, toàn bộ cấu trúc mạng nội bộ, IP, Port của các container Docker bị giấu nhẹm hoàn toàn khỏi internet.
2. Authentication & Authorization (Chốt chặn an ninh) Thay vì để 10 service phải tự đi lo xác thực, chúng ta nhét logic kiểm tra JWT Token vào Gateway. Gateway sẽ giải mã Token, xác nhận chữ ký. Nếu hợp lệ, nó "bóc" cái User_ID ra, nhét vào HTTP Header (ví dụ X-User-Id: 123) rồi đẩy xuống cho các service bên dưới. Lúc này, Service Ticket viết bằng Go hay Service CMS viết bằng Laravel bên dưới cứ vô tư móc Header ra xài mà không cần quan tâm Token mã hóa phức tạp ra sao nữa. Cửa ải khó nhất đã có bảo vệ lo!
3. Rate Limiting (Chống bão Request) Chỉ với vài dòng cấu hình trên Gateway (kết hợp với Redis), bạn có thể thiết lập luật: "Mỗi User_ID chỉ được phép gọi API mua vé tối đa 5 lần/giây". Đứa nào dùng tool spam vượt quá con số này, Gateway vả thẳng một HTTP 429 (Too Many Requests) vào mặt trước khi cái request rác đó kịp chạm tới các service nghiệp vụ bên trong.
Thực chiến API Gateway tại hệ thống AFC
Trở lại với hệ thống thu phí tự động (AFC) của tuyến Metro.
Bên trong hệ thống nội bộ là một mớ các service viết bằng đủ thứ ngôn ngữ (Laravel, Go, C++) chạy tán loạn. Nhưng khi Mobile App của hành khách (hoặc hệ thống của đối tác thanh toán như MoMo, VNPay) muốn giao tiếp với Metro, họ bắt buộc phải đi qua một cổng API Gateway duy nhất (có thể dùng Kong Gateway, Apache APISIX, hoặc đơn giản là Nginx được config cứng cáp).
Khi một đối tác đẩy giao dịch nạp tiền vào thẻ hành khách:
-
API Gateway kiểm tra API Key và chứng chỉ mã hóa của đối tác đó.
-
Thấy IP của đối tác này đang gửi 10.000 req/s (dấu hiệu bất thường), luật Rate Limit trên Gateway được kích hoạt, cản bớt traffic dư thừa lại.
-
Sau khi lọc sạch sẽ, Gateway mới bẻ lái (route) những request hợp lệ vào đúng con Service Nạp Tiền (Topup) nằm sâu trong mạng Private.
Các service bên trong hoàn toàn tĩnh lặng, an toàn, chỉ việc nhận cục data sạch sẽ và xử lý.
Lời khuyên "xương máu"
-
Đừng nhét Business Logic vào Gateway: Gateway chỉ nên làm nhiệm vụ cắt luồng, chuyển phát, và xác thực vòng ngoài. Nhiều anh em lạm dụng, nhét cả logic truy vấn Database, biến đổi dữ liệu (Data Transformation) vào Gateway. Hậu quả là Gateway phình to, chạy ì ạch và biến thành một cái "Monolith thế hệ mới" cực kỳ khó maintain.
-
Cẩn thận với Điểm chết tập trung (Single Point of Failure): Chết Service Mua vé thì không mua được vé, nhưng chết API Gateway là "sập toàn tập". Phải luôn thiết kế Gateway chạy ở dạng Cluster (nhiều node) và có Load Balancer đứng trước nó.
Với API Gateway, chúng ta đã xây được một bức tường thành vững chắc che chắn cho hệ thống. Nhưng đợi đã! Ở phần Routing, mình có nói Gateway sẽ forward request vào các IP nội bộ. Nhưng trong môi trường Docker hay Kubernetes, mỗi lần deploy hoặc scale up, container mới sẽ sinh ra một cái IP mới toanh. Làm sao Gateway biết IP mới là gì để mà forward?
Ở bài tiếp theo (Bài 8), chúng ta sẽ giải quyết bài toán động não này bằng khái niệm: Service Discovery – "Bản đồ sống" của Microservices.
Anh em ở công ty đang dùng con API Gateway nào (Kong, Nginx, Ocelot hay AWS API Gateway)? Đã bao giờ anh em phải vật vã cấu hình bảo mật ở tầng này chưa? Cùng bình luận nhé!
All rights reserved