+9

[gRPC] - gRPC Overview

Trong bài viết này mình sẽ overview về framework RPC của Google là gRPC để mọi người có cái nhìn được rõ ràng hơn. Đây là một trong những công nghệ khá HOT hiện nay.

Hoàn cảnh ra đời

Trong các hệ thống hiện nay hầu hết việc giao tiếp giữa các dịch vụ đều sử dụng kiến trúc REST bằng cách trao đổi kiểu dữ liệu JSON thông qua giao thức HTTP. JSON so với XML mà nói thì nhẹ và dễ đọc (meaning, dễ hiểu hơn). Còn REST đơn giản và dễ sử dụng. Vì vậy chúng ta cũng thường sử dụng REST Api khi giao tiếp giữa các Microservices trong các hệ thống phân tán. Tuy nhiên nó có những vấn đề sau:

  • HTTP/1.1 truyền tin dạng văn bản khá nặng. Mà Microservices trao đổi khối lượng thông tin JSON khổng lồ => điều này khá là không tốt.
  • Khi gửi HTTP request thì thông tin được gửi qua Header không được nén.
  • HTTP/1.1 khi chúng ta gửi một yêu cầu và sẽ chờ cho đến khi nhận được phản hồi lại. Chúng ta không thể gửi yêu cầu (request) khác cho đến khi nhận được phản hồi (response).
  • Khi gửi HTTP request nó sẽ thiết lập một kết nối TCP trước, điều này sẽ gây tốn thời gian nếu cứ mỗi lần gửi HTTP request đều phải thiết lập lại một kết nối TCP.
  • Dữ liệu dạng JSON là kiểu dữ liệu văn bản (text based) thân thiện với con người (dễ đọc) nhưng không thân thiện với máy. Khi chuyển dữ liệu cần có thời gian để deserialize và serialize. Quá trình này cũng sẽ gây chậm một phần cho việc giao tiếp giữa các dịch vụ.

Tất cả những điều này có thể ảnh hưởng đến hiệu suất tổng thể của ứng dụng kiến trúc Microservices. REST tốt khi giao tiếp giữa trình duyệt và back-end. Nhưng chúng ta cần một thứ gì đó tốt hơn REST cho giao tiếp giữa các Microservices để tránh các vấn đề đã đề cập ở trên.

Nắm được những điều này thì google đã nghiên cứu và cho ra đời công nghệ gRPC dựa trên protobuf và giao thức HTTP/2.

Trong gRPC, client application có thể gọi trực tiếp đến một phương thức trên server application ở một máy khác như thể đang gọi một phương thức cục bộ, điều này làm cho việc thiết kế các ứng dụng và dịch vụ phân tán dễ dàng hơn. Như trong nhiều hệ thống RPC, gRPC dựa trên ý tưởng là xác định các dịch vụ, chỉ định các phương thức có thể được gọi từ xa với các tham số và kiểu trả về. Phía server sẽ implements các phương thức này và chạy một máy chủ gRPC để xử lý các cuộc gọi từ client. Phía client sẽ cung cấp các phương thức giống hệt như trên server để gọi đến server.

Client và server có thể chạy và nói chuyện với nhau trong nhiều môi trường khác nhau và có thể được viết bằng bất kỳ ngôn ngữ nào được hỗ trợ của gRPC. Ví dụ có thể dễ dàng tạo một máy chủ gRPC bằng Java với các máy khách bằng Go, Python hoặc Ruby rất linh hoạt.

Protobuf (hay Protocol Buffers)

Đầu tiên nói về Protobuf, protobuf là một giao thức để tuần tự hoá dữ liệu có cấu trúc tương tự với JSON và XML. Bản chất Protobuf lưu trữ data dưới dạng binary nên tốc độ decode và encode nhanh hơn JSON rất nhiều.

Đầu tiên để làm việc với protocol buffers là xác định cấu trúc dữ liệu muốn serialize (hay còn gọi là message) và các dịch vụ trong một file proto: đây là một tệp văn bản thông thường với phần mở rộng là .proto. Từ file .proto này, tếp theo sử dụng trình biên dịch protoc để tạo ra class truy cập dữ liệu cho team phát triển client side và team phát triển server side theo các ngôn ngữ lập trình khác nhau. Vì source cùng được tạo từ một file .proto nên sẽ tránh được rủi ro dữ liệu trao đổi giữa các dịch vụ ở các bên không đồng nhất. Các class này sẽ chứa các phương thức truy cập để serialize/parse toàn bộ cấu trúc từ các byte thô và các phương thức bên trong dịch vụ. Client và server sẽ giao tiếp với nhau qua cấu trúc dữ liệu (message) và các phương thức đã định nghĩa đầu vào đầu ra trong file .proto. Cuối bài viết mình có để một số link tham khảo, mọi người có thể tìm hiểu chi tiết hơn.

HTTP/2

Có thể mọi người đã biết HTTP/1 dựa trên cơ chế 1 connection/1 tài nguyên tuy vẫn hoạt động tốt ở các trình duyệt ở thời điểm hiện tại nhưng chưa thực sự tối ưu về băng thông. Đội ngũ kỹ sư google lại tiếp tục nghiên cứu và cho ra đời giao thức HTTP/2 (phiên bản chính tiếp theo của HTTP) nhằm cải thiện tốc độ và hiệu suất duyệt web. Một số đặc điểm của HTTP/2 như:

Kỹ thuật ghép kênh (multiplexed)

Trước đây, đối với HTTP/1 khi vào một webside cần phải tải rất nhiều tài nguyên (js, csss, dữ liệu từ nhiều api...), mỗi 1 lần tải tài nguyên này sẽ cần 1 request (1 connection/1 tài nguyên). Việc này dẫn đến quá trình tải trang chậm chạp và trải nghiệm người dùng chưa tốt. Ở HTTP/2 thì Client và Server chỉ bắt tay qua một TPC Connection duy nhất, sau đó client và server có thể gửi nhận request/response mà không tạo ra thêm các connection mới.

Phản hồi ưu tiên (prioritization)

Ở HTTP/1 server nhận request và gửi phản hồi theo thứ tự nhận truy vấn. HTTP/2 giải quyết bài toán theo cách non-blocking và asyn vì vậy các truy vấn xử lý nhanh hơn sẽ được trả về trước.

Truyền dữ liệu dạng binary

Dữ liệu dạng nhị phân gọn nhẹ hơn, ít gặp phải các lỗi khi như khoảng trắng, viết hoa, ký tự đặc biệt, kết thúc dòng,.... như dạng text ở HTTP/1.

Server push

Ngay khi client tạo một TCP connection với server. Server có thể gửi lại các phản hồi mà client cần trước khi client gửi request.

Nén header

Ở HTTP/1, mỗi request gửi đi sẽ bao gồm thông tin trong header ở dạng text base. Ở HTTP/2, header sẽ được nén trước khi gửi đi, vì vậy request sẽ nhẹ và nhanh hơn.

Một số so sánh

gRPC mặc định sử dụng HTTP/2 request và Proto Buffers để trao đổi bản tin thay vì JSON trong khi hầu hết kiểu kiến trúc microservices hiện tại sử dụng HTTP/1.1 request với REST và JSON.

HTTP/1.1 vs HTTP/2

HTTP/1.1 HTTP/2
Dữ liệu truyền dạng text Dữ liệu truyền dạng Binary
Header là văn bản thuần túy (plain text), không được nén Dữ liệu trên Header dược nén
Mỗi HTTP request yêu cầu một kết nối TCP, gửi request và chờ cho đến khi nhận lại response Có thể sử dụng lại cùng một kết nối TCP để ghép kênh. (Server streaming, Client streaming, Bi-directional streaming)

Protocol Buffers vs JSON

JSON Protocol Buffers
Không có định nghĩa model (cấu trúc dữ liệu json) nghiêm ngặt Định nghĩa model nghiêm ngặt
Dạng văn bản thuần Dạng Binary
Dữ liệu văn bản làm quá trình serialization/deserialization dữ liệu khi gửi/nhận làm chậm hơn Dữ liệu Binary giúp quá trình serialization / deserialization nhanh hơn
Phải xử lý thủ công serialize và deserialize Sử dụng thư viện tự động gen code xử lý cho hầu hết các ngôn ngữ lập trình

Protocol Buffers vs JSON

REST gRPC
JSON Protocol Buffers
HTTP/1.1 HTTP/2
Single Request & Response Single Request/Response, ClientStreaming, ServerStreaming, Bi-Directional Streaming

Tổng kết

Trên đây là một số đặc điểm, một vài phép so sánh giữa gRPC và Rest. Hi vọng bài viết hữu ích với mọi người.

Nguồn tham khảo:

https://freecontent.manning.com/animation-http-1-1-vs-http-2-vs-http-2-with-push/ https://developers.google.com/protocol-buffers/docs/overview https://developers.google.com/protocol-buffers/docs/javatutorial)


All Rights Reserved

Viblo
Let's register a Viblo Account to get more interesting posts.