So sánh dịch vụ gRPC với HTTP APIs
Bài viết này giải thích cách dịch vụ gRPC so sánh với HTTP APIs với JSON (bao gồm cả ASP.NET Core web APIs). Công nghệ được sử dụng để cung cấp API cho ứng dụng là một lựa chọn quan trọng, và gRPC mang lại những lợi ích độc đáo so với HTTP APIs. Bài viết này thảo luận về điểm mạnh và điểm yếu của gRPC và đề xuất các tình huống sử dụng gRPC thay vì các công nghệ khác.
So sánh cấp cao
Bảng sau cung cấp so sánh cấp cao về các tính năng giữa gRPC và HTTP APIs với JSON.
| Tính năng | gRPC | HTTP APIs với JSON |
|---|---|---|
| Hợp đồng (Contract) | Bắt buộc (.proto) | Tùy chọn (OpenAPI) |
| Giao thức (Protocol) | HTTP/2 | HTTP |
| Payload (dữ liệu tải) | Protobuf (nhỏ, nhị phân) | JSON (lớn, đọc được bởi người) |
| Tính quy định | Đặc tả nghiêm ngặt | Lỏng lẻo. Bất kỳ HTTP nào đều hợp lệ. |
| Streaming (truyền dữ liệu) | Client, server, hai chiều | Client, server |
| Hỗ trợ trình duyệt | Không (yêu cầu grpc-web) | Có |
| Bảo mật | Transport (TLS) | Transport (TLS) |
| Tạo code client | Có | OpenAPI + công cụ bên thứ ba |
Điểm mạnh của gRPC
Hiệu suất
Các thông báo gRPC được tuần tự hóa sử dụng Protobuf, một định dạng thông báo nhị phân hiệu quả. Protobuf tuần tự hóa rất nhanh trên cả server và client. Việc tuần tự hóa Protobuf dẫn đến các payload thông báo nhỏ, quan trọng trong các tình huống băng thông hạn chế như ứng dụng di động.
gRPC được thiết kế cho HTTP/2, một bản sửa đổi lớn của HTTP cung cấp lợi ích hiệu suất đáng kể so với HTTP 1.x:
- Đóng khung và nén nhị phân. Giao thức HTTP/2 nhỏ gọn và hiệu quả trong cả gửi và nhận.
- Multiplexing (ghép kênh) nhiều lời gọi HTTP/2 qua một kết nối TCP duy nhất. Multiplexing loại bỏ head-of-line blocking (chặn đầu hàng).
HTTP/2 không dành riêng cho gRPC. Nhiều loại request, bao gồm cả HTTP APIs với JSON, có thể sử dụng HTTP/2 và hưởng lợi từ cải thiện hiệu suất của nó.
Tạo code
Tất cả các framework gRPC đều cung cấp hỗ trợ hạng nhất cho việc tạo code. File cốt lõi trong phát triển gRPC là file .proto, định nghĩa hợp đồng của dịch vụ và thông báo gRPC. Từ file này, các framework gRPC tạo ra một lớp cơ sở dịch vụ, thông báo và một client hoàn chỉnh.
Bằng cách chia sẻ file .proto giữa server và client, thông báo và code client có thể được tạo từ đầu đến cuối. Việc tạo code của client loại bỏ sự trùng lặp thông báo trên client và server, và tạo ra một client có kiểu dữ liệu mạnh cho bạn. Không cần phải viết client giúp tiết kiệm thời gian phát triển đáng kể trong các ứng dụng có nhiều dịch vụ.
Đặc tả nghiêm ngặt
Không tồn tại đặc tả chính thức cho HTTP API với JSON. Các nhà phát triển tranh luận về định dạng tốt nhất của URL, HTTP verb và response code.
Đặc tả gRPC quy định rõ ràng về định dạng mà dịch vụ gRPC phải tuân theo. gRPC loại bỏ tranh luận và tiết kiệm thời gian của nhà phát triển vì gRPC nhất quán trên các nền tảng và triển khai.
Streaming (truyền dữ liệu liên tục)
HTTP/2 cung cấp nền tảng cho các luồng giao tiếp thời gian thực, tồn tại lâu dài. gRPC cung cấp hỗ trợ hạng nhất cho streaming thông qua HTTP/2.
Dịch vụ gRPC hỗ trợ tất cả các kết hợp streaming:
- Unary (không streaming)
- Server-to-client streaming (server tới client)
- Client-to-server streaming (client tới server)
- Bi-directional streaming (hai chiều)
Deadline/timeout và cancellation (hủy bỏ)
gRPC cho phép client chỉ định thời gian họ sẵn sàng chờ để RPC hoàn thành. Deadline được gửi đến server, và server có thể quyết định hành động nào sẽ thực hiện nếu vượt quá deadline. Ví dụ, server có thể hủy các request gRPC/HTTP/database đang xử lý khi hết thời gian.
Truyền deadline và cancellation qua các lời gọi gRPC con giúp thực thi giới hạn sử dụng tài nguyên.
Các tình huống gRPC được khuyến nghị
gRPC phù hợp với các tình huống sau:
- Microservices (vi dịch vụ): gRPC được thiết kế cho giao tiếp có độ trễ thấp và thông lượng cao. gRPC rất phù hợp cho các microservice nhẹ mà hiệu quả là yếu tố quan trọng.
- Giao tiếp thời gian thực point-to-point: gRPC có hỗ trợ tuyệt vời cho bi-directional streaming. Dịch vụ gRPC có thể đẩy thông báo theo thời gian thực mà không cần polling (thăm dò).
- Môi trường đa ngôn ngữ (Polyglot environments): Công cụ gRPC hỗ trợ tất cả các ngôn ngữ phát triển phổ biến, làm cho gRPC trở thành lựa chọn tốt cho môi trường đa ngôn ngữ.
- Môi trường hạn chế mạng: Các thông báo gRPC được tuần tự hóa với Protobuf, một định dạng thông báo nhẹ. Thông báo gRPC luôn nhỏ hơn thông báo JSON tương đương.
- Inter-process communication (IPC - giao tiếp liên tiến trình): Các transport IPC như Unix domain socket và named pipe có thể được sử dụng với gRPC để giao tiếp giữa các ứng dụng trên cùng một máy. Để biết thêm thông tin, xem Inter-process communication with gRPC.
Điểm yếu của gRPC
Hỗ trợ trình duyệt hạn chế
Hiện tại không thể gọi trực tiếp dịch vụ gRPC từ trình duyệt. gRPC sử dụng nhiều tính năng HTTP/2 và không có trình duyệt nào cung cấp mức độ kiểm soát cần thiết đối với các yêu cầu web để hỗ trợ gRPC client. Ví dụ, các trình duyệt không cho phép người gọi yêu cầu sử dụng HTTP/2, hoặc cung cấp quyền truy cập vào các frame HTTP/2 cơ bản.
gRPC trên ASP.NET Core cung cấp hai giải pháp tương thích trình duyệt:
- gRPC-Web cho phép ứng dụng trình duyệt gọi dịch vụ gRPC bằng gRPC-Web client và Protobuf. gRPC-Web yêu cầu ứng dụng trình duyệt tạo gRPC client. gRPC-Web cho phép ứng dụng trình duyệt hưởng lợi từ hiệu suất cao và sử dụng mạng thấp của gRPC.
.NET có hỗ trợ tích hợp cho gRPC-Web. Để biết thêm thông tin, xem gRPC-Web in ASP.NET Core gRPC apps.
- gRPC JSON transcoding cho phép ứng dụng trình duyệt gọi dịch vụ gRPC như thể chúng là RESTful APIs với JSON. Ứng dụng trình duyệt không cần tạo gRPC client hay biết bất cứ điều gì về gRPC. RESTful APIs có thể được tạo tự động từ dịch vụ gRPC bằng cách chú thích file
.protovới metadata HTTP. Transcoding cho phép ứng dụng hỗ trợ cả gRPC và JSON web APIs mà không cần tốn công xây dựng các dịch vụ riêng biệt cho cả hai.
.NET có hỗ trợ tích hợp để tạo JSON web APIs từ dịch vụ gRPC. Để biết thêm thông tin, xem gRPC JSON transcoding in ASP.NET Core gRPC apps.
Lưu ý: gRPC JSON transcoding yêu cầu .NET 7 trở lên.
Không đọc được bởi người
Các yêu cầu HTTP API được gửi dưới dạng văn bản và có thể được đọc và tạo bởi con người.
Các thông báo gRPC được mã hóa bằng Protobuf theo mặc định. Mặc dù Protobuf hiệu quả trong việc gửi và nhận, nhưng định dạng nhị phân của nó không đọc được bởi người. Protobuf yêu cầu mô tả giao diện của thông báo được chỉ định trong file .proto để giải tuần tự hóa đúng cách. Cần có công cụ bổ sung để phân tích payload Protobuf trên mạng và để soạn các yêu cầu bằng tay.
Các tính năng như server reflection và gRPC command line tool tồn tại để hỗ trợ với các thông báo Protobuf nhị phân. Ngoài ra, các thông báo Protobuf hỗ trợ chuyển đổi sang và từ JSON. Việc chuyển đổi JSON tích hợp cung cấp một cách hiệu quả để chuyển đổi thông báo Protobuf sang và từ dạng đọc được bởi người khi gỡ lỗi.
Các tình huống framework thay thế
Các framework khác được khuyến nghị thay vì gRPC trong các tình huống sau:
- APIs có thể truy cập từ trình duyệt: gRPC không được hỗ trợ đầy đủ trong trình duyệt. gRPC-Web có thể cung cấp hỗ trợ trình duyệt, nhưng có các hạn chế và giới thiệu một server proxy.
- Giao tiếp thời gian thực dạng broadcast (phát sóng): gRPC hỗ trợ giao tiếp thời gian thực qua streaming, nhưng khái niệm phát sóng thông báo đến các kết nối đã đăng ký không tồn tại. Ví dụ trong tình huống phòng chat nơi các tin nhắn chat mới nên được gửi đến tất cả client trong phòng chat, mỗi lời gọi gRPC được yêu cầu để streaming riêng lẻ các tin nhắn chat mới đến client. SignalR là framework hữu ích cho tình huống này. SignalR có khái niệm kết nối liên tục và hỗ trợ tích hợp để phát sóng thông báo.