+5

gRPC - Quick start

Mayfest2023

Bài viết note trong quá trình bắt đầu với gRPC.

Overview

RPC được viết tắt bởi Remote Produce Call. Cho phép gọi một chương trình có thể gọi một hàm được cung cấp bởi chương trình khác.

gRPC = RPC + Protocol Buffers.

gRPC hoạt động dưới kiến trúc client-server.

Prerequisites

wget https://github.com/protocolbuffers/protobuf/releases/download/v3.20.3/protoc-3.20.3-linux-x86_64.zip
unzip protoc-3.20.3-linux-x86_64.zip -d ~/.local
rm -rf protoc-3.20.3-linux-x86_64.zip
  • Go plugins for the protocol compiler:
go install google.golang.org/protobuf/cmd/protoc-gen-go@v1.28
go install google.golang.org/grpc/cmd/protoc-gen-go-grpc@v1.2

export PATH="$PATH:$(go env GOPATH)/bin"

Kiểm tra:

go version
protoc --version
protoc-gen-go --version
protoc-gen-go-grpc --version
go version go1.19.4 linux/amd64
libprotoc 3.20.3
protoc-gen-go v1.28.1
protoc-gen-go-grpc 1.2.0

Get example

Các phần example được để chung trong repo grpc-go, clone repo này về để có code mẫu. Để ổn định thì sẽ clone code của bản release mới nhất là v1.52.3.

git clone -b v1.52.3 --depth 1 https://github.com/grpc/grpc-go
cd grpc-go/examples/helloworld

Run the example

  1. Compile và chạy code server:
go run greeter_server/main.go
  1. Compile và chạy code client:
go run greeter_client/main.go

Ouput:

2023/02/01 13:24:26 Greeting: Hello world

Đến đây, client output Hello world như trên tức là mình đã kết nối client + server gRPC thành công.

Sửa gRPC service

gRPC service được định nghĩa bằng file .proto (Protocol Buffers). Mình sẽ cần tìm hiểu sâu hơn về file này sau. Trước mắt, chỉ cần đọc và hiểu đoạn khai báo các method RPC của ví dụ trên:

// The greeting service definition.
service Greeter {
  // Sends a greeting
  rpc SayHello (HelloRequest) returns (HelloReply) {}
}

// The request message containing the user's name.
message HelloRequest {
  string name = 1;
}

// The response message containing the greetings
message HelloReply {
  string message = 1;
}

Tạm hiểu là:

  • Khai báo một service Greeter
  • Service Greeter chứa một method RPC có tên là SayHello(), nhận tham số có kiểu là HelloRequest và trả về kết quả có kiểu là HelloReply

Generate gRPC code

Nhiệm vụ của chúng ta là thêm một method RPC nữa SayHelloAgain(), hoạt động tương tự như SayHello(). Sửa file examples/helloworld/helloworld.proto:

Sử dụng protoc để generate code cho Go:

protoc --go_out=. --go_opt=paths=source_relative \
    --go-grpc_out=. --go-grpc_opt=paths=source_relative \
    helloworld/helloworld.proto

Hai file được generate ra là helloworld.pb.gohelloworld_grpc.pb.go. Mình đoán .pb.go là với subfix pb viết tắt của Protocol Buffers 😄

Xem qua code được generate:

// The request message containing the user's name.
type HelloRequest struct {
	state         protoimpl.MessageState
	sizeCache     protoimpl.SizeCache
	unknownFields protoimpl.UnknownFields

	Name string `protobuf:"bytes,1,opt,name=name,proto3" json:"name,omitempty"`
}

// ...

File này có khá nhiều nội dung khác nhưng trước mắt, cái mình nhận thấy nhất là cái message HelloRequest đã được generate ra, và cũng có field Name như kỳ vọng.

Tiếp theo, method SayHelloAgain cũng đã được generate:

// For semantics around ctx use and closing/ending streaming RPCs, please refer to https://pkg.go.dev/google.golang.org/grpc/?tab=doc#ClientConn.NewStream.
type GreeterClient interface {
	// Sends a greeting
	SayHello(ctx context.Context, in *HelloRequest, opts ...grpc.CallOption) (*HelloReply, error)
	// Sends another greeting
	SayHelloAgain(ctx context.Context, in *HelloRequest, opts ...grpc.CallOption) (*HelloReply, error)
}

All Rights Reserved

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