
gRPC là gì là câu hỏi thường gặp khi team backend chuyển từ kiến trúc monolith sang microservices. gRPC là framework Remote Procedure Call do Google phát triển, hiện được maintain bởi CNCF và là một trong những chuẩn giao tiếp service-to-service phổ biến nhất trong hệ thống phân tán. Bài viết này giải thích gRPC hoạt động như thế nào, vì sao nó nhanh hơn REST/JSON, và khi nào nên chọn.

Điểm khác biệt cốt lõi của gRPC so với REST là nó không gửi “gói tin” tự do. Thay vào đó, hệ thống định nghĩa sẵn một hợp đồng (contract) giữa client và server, và mọi lời gọi đều tuân theo hợp đồng đó. Nhờ vậy lỗi sai định dạng dữ liệu gần như bị loại bỏ ngay từ khâu thiết kế.
gRPC là gì: định nghĩa cốt lõi
Theo định nghĩa trên Wikipedia, gRPC là một framework RPC hiệu năng cao, đa nền tảng, ban đầu do Google tạo ra nhưng đã mã hoá nguồn mở. Nó dùng Protocol Buffers làm định dạng tuần tự hoá mặc định và HTTP/2 làm giao thức vận chuyển.
Ba thành phần chính của một hệ thống gRPC:
- Protocol Buffers — ngôn ngữ định nghĩa interface, sinh ra code client và server cho nhiều ngôn ngữ lập trình.
- HTTP/2 — cho phép nhiều lời gọi (streams) chạy song song trên một kết nối TCP duy nhất.
- grpc-java, grpc-go, grpc-python… — thư viện runtime cho từng ngôn ngữ.

gRPC hoạt động như thế nào
Quy trình một lời gọi gRPC đi qua 5 bước:
- Client serialize đối tượng thành bytes theo schema Protobuf đã định nghĩa.
- Gửi kèm metadata (header) và số thứ tự message lên HTTP/2 stream.
- Server deserialize bytes thành đối tượng, chạy xử lý nghiệp vụ.
- Trả kết quả với cùng cơ chế stream.
- Client nhận và deserialize ngược lại.
Điểm mấu chốt: server chỉ cần biết schema, không cần biết client viết bằng ngôn ngữ nào. Đây là lý do gRPC rất phù hợp khi đội ngũ dùng đa ngôn ngữ — ví dụ service Go giao tiếp với service Python và service Java mà không cần viết adapter thủ công.
gRPC so với REST: bảng đối chiếu
| Tiêu chí | gRPC | REST + JSON |
|---|---|---|
| Định dạng dữ liệu | Protocol Buffers (binary) | JSON (text) |
| Hiệu năng serialize | Rất nhanh, nhỏ gọn | Chậm hơn, payload lớn |
| Streaming | Native: unary, server, client, bidirectional | Không chuẩn hoá, phải hack |
| Khám phá API | Cần công cụ reflection hoặc file .proto | Tự mô tả qua OpenAPI |
| Dễ đọc khi debug | Cần grpcurl hoặc proxy | curl, Postman đều dùng được |
| Bộ lọc và cache | Không có | Có HTTP cache chuẩn |
| Trình duyệt gọi trực tiếp | Không (cần proxy gRPC-web) | Có |
Đừng hiểu gRPC là “REST thay thế hoàn toàn”. Trong kiến trúc thực tế, cả hai thường cùng tồn tại: gRPC cho service nội bộ, REST/JSON cho API public mà frontend hoặc đối tác bên ngoài tiêu thụ.
Cấu trúc file .proto đơn giản nhất
Mọi thứ bắt đầu từ một file định nghĩa. Ví dụ định nghĩa service đặt hàng:
syntax = "proto3";
package shop;
service OrderService {
rpc GetOrder (GetOrderRequest) returns (Order);
rpc StreamOrders (ListRequest) returns (stream Order);
}
message GetOrderRequest {
string order_id = 1;
}
message ListRequest {
int32 page = 1;
}
message Order {
string id = 1;
string customer = 2;
int64 total_vnd = 3;
string status = 4;
}
Lưu ý số thứ tự field (1, 2, 3, 4) chính là field number. Số này được ghi thẳng vào wire format nên tuyệt đối không được đổi hoặc tái sử dụng sau khi đã deploy. Nếu cần bỏ một field, hãy để trống và giữ nguyên số.
Các kiểu lời gọi (RPC pattern)
- Unary — một request, một response. Giống REST POST nhưng nhanh hơn.
- Server streaming — một request, nhiều response. Dùng cho
rpc StreamOrders (ListRequest) returns (stream Order)ở trên. - Client streaming — nhiều request, một response. Dùng khi client gửi hàng loạt bản ghi.
- Bidirectional streaming — hai chiều cùng lúc. Phù hợp chat, log streaming, giao dịch chứng khoán realtime.
Code lời gọi gRPC bằng Python
Thư viện grpcio và grpcio-tools sinh code stub từ file .proto:
# Sinh code từ schema
python -m grpc_tools.protoc
-I. --python_out=. --grpc_python_out=. shop.proto
# Client
import grpc
from shop_pb2 import GetOrderRequest
from shop_pb2_grpc import OrderServiceStub
channel = grpc.insecure_channel("localhost:50051")
stub = OrderServiceStub(channel)
resp = stub.GetOrder(GetOrderRequest(order_id="OD-1001"))
print(resp.customer, resp.total_vnd, resp.status)
Server tương ứng chỉ cần một hàm xử lý và đăng ký service:
from concurrent import futures
import grpc
from shop_pb2_grpc import add_OrderServiceServicer_to_server
from shop_pb2 import GetOrderRequest, Order
class OrderService(add_OrderServiceServicer_to_server):
def GetOrder(self, request, context):
return Order(id=request.order_id, customer="Nguyen Van A",
total_vnd=450000, status="shipping")
server = grpc.server(futures.ThreadPoolExecutor(max_workers=10))
add_OrderServiceServicer_to_server(OrderService(), server)
server.add_insecure_port("[::]:50051")
server.start()
server.wait_for_termination()
Điều kiện bắt buộc khi dùng gRPC trong production
1. Bắt buộc dùng TLS
insecure_channel chỉ dùng cho môi trường local. Trong production phải chuyển sang secure_channel với chứng chỉ để dữ liệu không bị nghe lấm vào sự cố trung gian. Nhiều tiêu chuẩn compliance bắt buộc mã hoá đường truyền nội bộ.
2. Timeout bắt buộc ở mọi lời gọi
Không đặt timeout là cách phổ biến nhất để làm sập cả hệ thống. Một service chậm sẽ giữ chân thread của caller và lan toả sang các service phụ thuộc. Luôn đặt deadline rõ ràng:
resp = stub.GetOrder(
GetOrderRequest(order_id="OD-1001"),
timeout=2.0, # giây
metadata=(("authorization", "Bearer ..."),),
)
3. Thiết kế lỗi có cấu trúc
Thay vì trả thông báo tự do, hãy dùng google.rpc.Status kèm mã lỗi chuẩn. Điều này giúp phía client xử lý lỗi nhất quán, đặc biệt khi có retry hay circuit breaker.
4. Theo dõi với OpenTelemetry
gRPC đã hỗ trợ interceptor để gắn trace ID và metric. Kết hợp với hệ thống quan sát hiện đại, bạn sẽ thấy được độ trễ theo từng phương thức mà không cần sửa code nghiệp vụ.
Khi nào nên chọn gRPC, khi nào nên dùng REST
| Chọn gRPC khi | Chọn REST khi |
|---|---|
| Giao tiếp nội bộ giữa nhiều service | API public cho bên thứ ba |
| Cần streaming dữ liệu | Đội frontend cần gọi trực tiếp |
| Đội đa ngôn ngữ lập trình | Cần bộ lọc, cache HTTP chuẩn |
| Độ trễ và băng thông là ưu tiên hàng đầu | Cần hệ sinh thái, tài liệu, công cụ sẵn có |
| Hợp đồng API ổn định, ít thay đổi | Yêu cầu thay đổi nhanh và thường xuyên |
Kết luận
gRPC mang lại hiệu năng vượt trội và hợp đồng interface chắc chắn, đổi lại là độ phức tạp khi debug và trải nghiệm phát triển không tốt bằng REST. Nếu hệ thống của bạn có hàng chục service gọi nhau liên tục với payload lớn, chuyển đường trong giao tiếp nội bộ sang gRPC thường mang lại cải thiện rõ rệt. Nhưng với API mở ra ngoài, REST vẫn là lựa chọn an toàn và dễ tiếp cận hơn.
Tài liệu chính thức của dự án nằm tại grpc.io — Core concepts, còn đặc tả định dạng dữ liệu nằm ở protobuf.dev. Nếu bạn đang tìm hiểu chủ đề liên quan, hãy xem thêm bài kiến trúc Transformer và OpenTelemetry cho microservices.
