Giới thiệu về gRPC

RPC viết tắt của Remote Procedure Call, là một cơ chế cho phép các bạn có thể call một function hay một method của một chương trình trên máy này từ một máy khác. Nó cũng giống như RMI, Remote Method Invocation, trong Java vậy đó các bạn! gRPC là một implementation, một framework open source, high performance của Google dành cho RPC. Trong bài viết này, mình sẽ giới thiệu với các bạn một số kiến thức cơ bản về gRPC và hiện thực một ví dụ để xem cách hoạt động của gRPC là như thế nào các bạn nhé!

Điều đầu tiên mình cần nói với các bạn là gRPC hỗ trợ cho nhiều ngôn ngữ khác nhau. Cho Java, chúng ta sẽ sử dụng gRPC Java ở đây https://grpc.io/docs/languages/java/

Với gRPC, message được gửi đi sẽ dưới dạng binary sử dụng protocol buffer (protobuf). Nói nôm na thì protocol buffer là một protocol không phụ thuộc vào ngôn ngữ lập trình hay nền tảng, được sử dụng để tuần tự hoá các dữ liệu có cấu trúc. Nhờ đó mà các ngôn ngữ khác nhau có thể serialize hoặc deserialize các message của gRPC một cách dễ dàng.

Và gRPC sử dụng HTTP/2 để thiết lập communication giữa các bên với nhau đó các bạn!

Bây giờ, mình sẽ thử làm một ví dụ tạo mới một gRPC server với Java và sử dụng Postman để call một method bên trong gRPC server này xem sao các bạn nhé!

Mình sẽ tạo mới một Maven project để làm ví dụ:

Các bạn hãy khai báo các gRPC dependencies như sau:

với “grpc.version” có giá trị như sau:

Chúng ta sẽ bắt đầu xây dựng gRPC server bằng cách định nghĩa các service mà gRPC server cung cấp sử dụng một tập tin .proto.

Định nghĩa service contract

Nội dung của tập tin .proto này sẽ định nghĩa protocol, service contract theo định dạng của Google Protocol Buffer các bạn nhé!

Mình sẽ tạo mới tập tin helloworld.proto trong thư mục /src/main/proto:

để định nghĩa một service đơn giản trả về dòng chữ “Hello <name> from Huong Dan Java” khi được gọi tới.

Nội dung của tập tin .proto này như sau:

Protocol Buffer hiện tại có 2 version: 2 và 3. Mình sẽ sử dụng version 3 như các bạn thấy trong dòng syntax = “proto3” ở trên.

Sau khi định nghĩa service contract sử dụng tập tin .proto, chúng ta sẽ sử dụng công cụ Protocol Buffer Compiler của gRPC để generate source code. Mặc định thì công cụ này sẽ generate các Java code vào trong 1 tập tin .java. Chúng ta sử dụng option java_multiple_files = true để thay đổi cấu hình mặc định này. Khi đó, Protocol Buffer Compiler sẽ generate thành các tập tin .java riêng biệt đó các bạn!

Chúng ta định nghĩa package sử dụng từ khóa package như trong Java các bạn nhé!

Để định nghĩa các message sẽ được sử dụng để trao đổi giữa các hệ thống với gRPC, chúng ta sử dụng từ khóa message cùng với định nghĩa nội dung của message đó. Như ví dụ trên, mình đang định nghĩa 2 message khác nhau là HelloRequest và Hello Response. Mỗi message sẽ chứa các attribute cùng với kiểu dữ liệu và thứ tự của các attribute này trong message.

Từ khóa service được sử dụng để định nghĩa các service mà gRPC sẽ expose ra bên ngoài. Mỗi service sẽ chứa nhiều operation và chúng ta sẽ sử dụng từ khóa rpc để định nghĩa cho các operation này. Như các bạn thấy, chúng ta sẽ sử dụng các message để làm input và output cho các operation.

Như vậy là chúng ta đã có một gRPC service contract đơn giản. Giờ là lúc chúng ta sẽ sử dụng Protocol Buffer Compiler để generate các Java code để implement service này. 

Các bạn có thể tham khảo bài viết này để generate Java code các bạn nhé!

Sau khi đã generate Java code, chúng ta cần implement phương thức hello() của class HelloServiceImplBase trong tập tin HelloServiceGrpc để hoàn thiện gRPC service của chúng ta.

Hiện thực gRPC service

Các bạn có thể tạo mới một class extends class HelloServiceImplBase và hiện thực phương thức hello() như sau:

Chúng ta sẽ sử dụng đối tượng của class StreamObserver để trả về kết quả cho client mỗi khi có request tới, sau khi build đối tượng HelloResponse các bạn nhé!

Bây giờ, chúng ta sẽ thêm code để hiện thực gRPC server trong phương thức main() của ứng dụng như sau:

Chúng ta sẽ chạy gRPC server sử dụng port 8080 với service trỏ tới service mà chúng ta đã implement ở trên. Như các bạn thấy, mình đã sử dụng class Server của gRPC Java để làm việc này.

Chúng ta cần call phương thức awaitTermination() để giữ cho gRPC server chạy cho đến khi chúng ta terminate ứng dụng các bạn nhé!

Bây giờ, nếu các bạn chạy ứng dụng rồi sử dụng Postman để gọi tới operation hello của gRPC server với message:

các bạn sẽ thấy kết quả như sau:

Như vậy là chúng ta đã hiện thực được một gRPC server cơ bản rồi đó các bạn!

Add Comment