Xây dựng Login gRPC API với Node.js và Express (Phần 1)
Dưới thời huy hoàng và phát triển rực rỡ từ REST API, cơ bản là giao tiếp giữa client và server đã được giải quyết khá tốt. Nhưng dưới thời đại Microservices, rõ ràng chúng ta cần một phương pháp tốt hơn để tăng tải và thông lượng giữa các services.
Có thể các bạn sẽ không thấy đây là một vấn đề chẳng đáng để bận tâm xử lý, đặc biệt khi hệ thống có ít services, ít server/node. Ở đây chúng ta đang nói đến rất nhiều services và tải đang rất cao. Ví dụ vài trăm service và tải đâu đó ở ngưỡng trên 100k CCU – Concurrent users (số lượng user đang hoạt động cùng một thời điểm).
Khi đó nếu một request cần phải tổng hợp dữ liệu qua nhiều services. Ở mỗi đầu service khi nhận các request trung gian này, chúng phải encode và decode liên tục (VD: JSON data). Việc này có thể gây quá tải cho các CPU. Lẽ ra CPU nên dành cho việc khác quan trọng hơn là chỉ vì en/code dữ liệu trung gian.
Ý tưởng về việc làm thế nào để các service giao tiếp với nhau với tốc độ cao nhất, giảm tải encode/decode data chính là lý do thúc đẩy gRPC ra đời.
RPC không phải REST API
- REST API: Client và Server cần trao đổi state thông qua các resource được trả về. Do đó các response trả về thường là một resource.
- RPC: Client cần server thực hiện tính toán hoặc trả về một thông tin cụ thể nào đó. Bản chất giống y như ta đang gọi hàm, chỉ là hàm đó ở máy chủ khác hoặc service khác. Từ đó response trả về chỉ là kết quả của “hàm” thôi, không hơn, không kém.
- POST /songs/:id/play (play bài hát, thành công thì return true hoặc 1)
- GET /songs/:id/calculate_total_views (trả về con số tổng lượt xem của bài hát)
- Một giao thức mới để tối ưu các connection, đảm bảo dữ liệu đi trao đổi liên tục với ít băng thông nhất có thể.
- Một định dạng dữ liệu mới để 2 đầu service (hoặc client và server) có thể hiểu được các message của nhau mà ít phải encode/decode.
- gRPC nên dùng để giao tiếp backend to backend. CPU không gánh nhiều cost cho encode/decoding mỗi đầu nữa. Tuy nhiên đặc tính mỗi đầu cần import file model chung (gen từ protobuf file) nên nếu update thì phải update đủ. Việc này vô tình tạo dependency cho các bên sử dụng, có thể nhiều bạn sẽ không thích điều này.
- gRPC thường được đấu nối vào service mesh (hoặc sidecar trong Microservices), để có thể xử lý connection HTTP/2 cũng như monitoring nó tốt hơn.
- gRPC support streaming 2 đầu nên rất được lòng các fan streaming system, event sourcing (stream event). VD: gRPC được sử dụng trong: vitess, neo4j vì lý do trên.
- gRPC nếu dùng cho frontend-backend thì thật sự rất cân nhắc. Connection statefull tạo nhiều sự khó chịu trong scale tải hoặc bạn có thể bị Head of line blocking (HOL).
- gRPC vẫn có thư viện gRPC Gateway chính chủ của Google. Tức là các bạn vẫn có thể chạy 1 port http/1 cho REST và 1 port http/2 của gRPC đồng thời. Như vậy không phải là không có cách để quay về REST thân quen, nhưng đương nhiên là đi qua proxy service nên cồng kềnh hơn.
Nhận xét
Đăng nhận xét