💬

gRPC × Golangでマイクロサービス間通信をやってみる

2022/03/30に公開

はじめに

マイクロサービス構成のWebサービスを開発する際に選択される技術としてgRPCが採用される事例が増えているようです。
今回は、近年注目が集まっているgRPCの基本的な扱い方を学んだので、記事にまとめようと思います。

gRPCとは

簡単にまとめると、マイクロサービス化されたWebサービスにおいて、マイクロサービス間通信を行う際に利用されるようです。
基本的に proto ファイルに諸々の設定を定義して所定のコマンドを打つと、通信に必要なソースコードを自動生成してくれるそうです。
proto ファイルに記述された内容が、ある種のドキュメントの役割も担ってくれるようですね。

※ gRPCの基本事項についての参考記事
https://qiita.com/oohira/items/63b5ccb2bf1a913659d6
https://qiita.com/gold-kou/items/a1cc2be6045723e242eb

protocol buffersの各messageのフィールドに付与される数字について

protoファイルの各メッセージを定義する際に以下の様に = 1= 2 という形式で数字を付与するかと思います。

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

各messageに付与される数字はmessage内においてフィールドを一意に特定するための識別子であるそうです。

message <定義するメッセージ型の名前> {
  <型> <フィールド名1> = <そのフィールドに紐づけるフィールド番号>;
  <型> <フィールド名2> = <そのフィールドに紐づけるフィールド番号>;
  <型> <フィールド名3> = <そのフィールドに紐づけるフィールド番号>;
  :
  :
}

事前準備

protoコマンドを実行するためのパッケージをローカル環境にインストールする必要がああります。

1. パッケージをインストール

$ go install google.golang.org/protobuf/cmd/protoc-gen-go@v1.26
$ go install google.golang.org/grpc/cmd/protoc-gen-go-grpc@v1.1

2. パスを通す

$ export PATH="$PATH:$(go env GOPATH)/bin"
https://grpc.io/docs/languages/go/quickstart/

ちなみに、protoコマンドを打つ際にパスが通っていないと以下のエラーが出るので注意しましょう。

protoc-gen-go: program not found or is not executable Please specify a program using absolute path or make sure the program is available in your PATH system variable --go_out: protoc-gen-go: Plugin failed with status code 1.

まずは公式チュートリアルをやってみる

公式チュートリアルにハンズオン形式のものがあるのでまずはそちらをさらっとやってみる。

https://grpc.io/docs/languages/go/basics/

1.リポジトリをクローン

リポジトリをクローンしたのち所定のリポジトリに入る。

$ git clone -b v1.35.0 https://github.com/grpc/grpc-go
$ cd grpc-go/examples/route_guide

2. 通信用のソースコードを生成する

$ protoc --go_out=. --go_opt=paths=source_relative \
    --go-grpc_out=. --go-grpc_opt=paths=source_relative \
    routeguide/route_guide.proto

3. gRPCサーバーを起動する

$ go run server/server.go

※ 別ターミナルで実行
$ go run client/client.go

4. 出力結果確認

クライアントサーバーを起動して以下の出力があれば、通信が成功している模様ですね。

Getting feature for point (409146138, -746188906)
name:"Berkshire Valley Management Area Trail, Jefferson, NJ, USA" location:<latitude:409146138 longitude:-746188906 >
Getting feature for point (0, 0)
location:<>
Looking for features within lo:<latitude:400000000 longitude:-750000000 > hi:<latitude:420000000 longitude:-730000000 >
name:"Patriots Path, Mendham, NJ 07945, USA" location:<latitude:407838351 longitude:-746143763 >
...
name:"3 Hasta Way, Newton, NJ 07860, USA" location:<latitude:410248224 longitude:-747127767 >
Traversing 56 points.
Route summary: point_count:56 distance:497013163
Got message First message at point(0, 1)
Got message Second message at point(0, 2)
Got message Third message at point(0, 3)
Got message First message at point(0, 1)
Got message Fourth message at point(0, 1)
Got message Second message at point(0, 2)
Got message Fifth message at point(0, 2)
Got message Third message at point(0, 3)
Got message Sixth message at point(0, 3)

とはいえ、公式チュートリアルのソースコードはほぼ完成されてしまっているので、手順通りにやるとうまくいくのは当たり前ですよね。
やっぱり、自分で試行錯誤しながらポートフォリオなどの成果物に落とし込んだ方がよさそうです。
ということで、ここからは自分で試行錯誤しながら作成したgRPCの通信部分のソースコードを載せていきたいと思います。

自分でやってみる

公式チュートリアルや他の方が作成したリポジトリを参考に自分でgRPCサーバーを構築していきたいと思います。
ちなみにソースコードはこちら

https://github.com/takuyanagai0213/GraphParadiseUserService/tree/main/users/grpc

ディレクトリ構成

grpc
├── server.go
└── userserive
       ├── user.pb.go
       └── user.proto

protoファイルを作成する

gRPCサーバーの定義を記述していきます。

user.proto
syntax = "proto3";

package userservice;

option go_package = "/;userservice";

message User {
  string Name = 2;
  string Password = 3;
  string Area = 4;
}

message ReadUserRequest{
    string name = 1;
}

message ReadUserResponse {
    User user = 1;
}

message ListUserRequest {
}

message ListUserResponse {
  repeated User user=1;
}

service UserService {
  rpc ReadUser(ReadUserRequest) returns (ReadUserResponse);
  rpc ListUser(ListUserRequest) returns (ListUserResponse);
}

protoコマンドを実行して通信用のソースコードを作成

こちらのコマンドを実行すると自動で通信用のソースコードが作成されます。

protoc user.proto --go_out=plugins=grpc:.

※参考記事
https://qiita.com/shiei_kawa/items/136aa864236699f32ae1

Discussion