gRPC với Protocol Buffers: Giao Thức RPC Hiệu Năng Cao Cho Dịch Vụ Microservice

gRPC với Protocol Buffers: Giao Thức RPC Hiệu Năng Cao Cho Dịch Vụ Microservice

gRPC là framework RPC do Google phát triển, dùng Protocol Buffers (protobuf) làm định dạng tuần tự hóa dữ liệu. Khác với REST JSON, gRPC truyền dữ liệu dưới dạng binary nhẹ hơn 5–10×, hỗ trợ truyền stream hai chiều và qua mạng HTTP/2. Đây là lựa chọn hàng đầu khi cần kết nối giữa các service nội bộ với độ trễ thấp và throughput cao.

Digital tech visualization showing cascading code streams

Protocol Buffers Là Gì?

Protocol Buffers (protobuf) là ngôn ngữ tuần tự hóa cấu trúc dữ liệu của Google. Thay vì mô tả bằng JSON (text), bạn định nghĩa schema bằng file .proto:

syntax = "proto3";
service UserService {
  rpc GetUser(GetUserRequest) returns (User);
  rpc StreamUpdates(stream UpdateRequest) returns (stream User);
}
message User {
  int64 id = 1;
  string name = 2;
  string email = 3;
}

Trình biên dịch protoc sinh ra mã cho 10+ ngôn ngữ (Go, Python, Java, C++, Rust…). Khi runtime, protobuf chuyển đổi User{id:1,name:"Hùng",email:"[email protected]"} thành chuỗi byte nhị phân — chỉ 10 byte thay vì ~50 byte của JSON tương đương. Điều này có nghĩa dung lượng truyền giảm 80% và parsing nhanh hơn 2–3× so với JSON parser.

Bốn Kiểu RPC trong gRPC

gRPC hỗ trợ bốn mô hình giao tiếp:

Mô hình Mô tả Use case
Unary Client gửi 1 request, nhận 1 response API thông thường
Server-streaming Client gửi 1 request, nhận nhiều responses Pagination, batch download
Client-streaming Client gửi nhiều requests, nhận 1 response Upload lớn, log aggregation
Bidirectional streaming Hai chiều truyền stream đồng thời Real-time chat, WebSocket thay thế

Trong bidirectional streaming, một kênh HTTP/2 duy nhất vận chuyện hai chiều. Khác với REST (mở kết nối mới cho mỗi request), gRPC duy trì kết nối lâu dài — giảm overhead TCP handshake, TLS negotiation lên đến 90% trong các service giao tiếp liên tục.

Code editor screen showing PHP and HTML syntax highlighting

Ví dụ: Bidirectional Streaming

Trong một ứng dụng chat, cả client và server đều mở một stream. HTTP/2 multiplexing cho phép chạy đồng thời nhiều stream trên một kết nối TCP, giảm overhead so với WebSocket mở nhiều kết nối riêng.

Code Go server:

func (s *server) Chat(stream pb.ChatService_ChatServer) error {
  for {
    msg, err := stream.Recv()
    if err == io.EOF { return nil }
    stream.Send(&pb.Message{User: msg.User, Text: "Echo: " + msg.Text})
  }
}

Client Go:

stream, err := client.Chat(ctx)
go func() {
    for {
        msg, err := stream.Recv()
        // print message
    }
}()
// send messages
stream.Send(&pb.Message{User: me, Text: text})

Hiệu Năng: gRPC vs REST

Theo benchmark của SkySkinner, gRPC xử lý JSON khoảng 852k req/s, trong khi REST JSON đạt ~154k req/s — nhanh hơn 5.5×. Với protobuf nhị phân, tốc độ lên tới 1.2 triệu req/s. Tuy nhiên, gRPC không thể dùng trực tiếp trong trình duyệt (trừ khi dùng gRPC-Web + proxy Envoy).

HTTP/2 dưới Một Góc Nhìn

HTTP/2 mang lại ba lợi ích then chốt cho gRPC:

  • Multiplexing: nhiều request/response trên một kết nối TCP — không còn head-of-line blocking như HTTP/1.1
  • Header nén: HPACK giảm header overhead lên đến 90%
  • Server push: server có thể đẩy data trước khi client yêu cầu

Tuy nhiên, do dùng TCP, gRPC có thể gặp head-of-line blocking ở tầng TCP khi mạng packet loss. QUIC transport (trên UDP) đang được khám phá để khắc phục. gRPC over QUIC (gQUIC) đang được Google thử nghiệm nội bộ.

Hệ Sinh Thái và Công Cụ

grpc-gateway sinh ra API REST từ file .proto, giúp frontend vẫn dùng JSON còn backend dùng gRPC nội bộ. gRPC reflection cho phép công cụ như grpcurl gọi service mà không cần stub — chỉ cần biết tên service và method.

Connect của Buf là lựa chọn mới, kết hợp gRPC + HTTP/JSON trong một API thống nhất. Hỗ trợ cả browser (fetch-based) và server. Envoy proxy là reverse proxy tiêu chuẩn cho gRPC — hỗ trợ load balancing, retry, circuit breaker, auth.

Framework hỗ trợ gRPC phổ biến: Go (google.golang.org/grpc — ngôn ngữ chủ đạo), Python (grpcio), Rust (tonic), Java (grpc-java), Node.js (@grpc/grpc-js).

Những Lưu Ý Khi Dùng gRPC

Đối với hệ thống microservice cần hiệu năng cao, gRPC + protobuf là kết hợp khó thể bỏ qua. Chỉ số serialization siêu nhẹ, stream hai chiều, HTTP/2 multiplexing — tất cả trong một framework được Google dùng hàng năm. Tuy nhiên, gRPC phù hợp cho nội bộ (service-to-service), không nên dùng cho public API vì khó debug, không thể test bằng curl trực tiếp. Luôn dùng grpc-gateway hoặc Envoy nếu cần proxy.

Phiên bản protobuf mới (protobuf 26+) hỗ trợ Editions, cho phép cập nhật ngôn ngữ mà không cần migrate schema — một cú pháp mới, cùng format cũ. Server và client cũ vẫn đọc được schema mới nhờ backward-compatible wire format — đảm bảo migrating hệ thống lớn không bị đứt kết nối.

Tôi là một lập trình viên IOS. Code chính là IOS nhưng thỉnnh thoảng vẫn đá sang Android hoặc web. Mặc dù không quá thông thạo nhưng tôi sẽ chia sẻ những kiến thức mà mình đã tìm hiểu, áp dụng qua.

Bài viết liên quan

Deno Deploy: Serverless TypeScript Global Được Hỗ Trợ Tính Năng Sẵn

Deno Deploy là gì? Deno Deploy là nền tảng serverless chạy JavaScript và TypeScript trên toàn cầu, phát triển bởi Deno Land. Đây là phiên bản hoàn toàn mới của…

Xem thêm

Hono Framework — Web Framework Siêu Nhẹ Chạy Trên Mọi Môi Trường

Hono Framework — Web Framework Siêu Nhẹ, Chạy Tren Moi Môi Trường Hono là web framework viết bằng TypeScript, thiết kế để chạy nhất quán trên mọi nền tảng: Cloudflare…

Xem thêm

Rust Async Trait: Mô Hình Bất Đồng Bộ Kiểu An Toàn Cho Lập Trình Hiện Đại

Rust Async Trait: Mô Hình Bất Động Bộ Kiểu An Toàn Rust async trait là một pattern phát triển trong hệ sinh thái Rust để định nghĩa các trait có…

Xem thêm
0 0 đánh giá
Article Rating
Theo dõi
Thông báo của
guest
0 Comments
Cũ nhất
Mới nhất Được bỏ phiếu nhiều nhất