Open8
Go言語とgRPCで学ぶマイクロサービス開発

gRPCの特徴
- 高速なバイナリ形式の通信
- 多様なデータ型をサポート
- 双方向ストリーミング
- ヘッダーのデータ圧縮を実現
https://github.com/grpc/grpc/blob/master/doc/PROTOCOL-HTTP2.md

Protocol Buffersの構成要素
- インターフェース定義言語(IDL)
- シリアライズ形式
- プログラミング言語向けランタイムライブラリ
- プロとコンパイラにより生成されるコード
Protocol Buffersの特徴
- シンプルなデータ形式
- 相互運用性
- 拡張性
- バージョン管理
- データフォーマット
- 自動生成

基本言語使用
-
protobufのプログラミングガイド
https://protobuf.dev/programming-guides/ -
共通項目(バージョン3の場合)
- ライセンスヘッダ
- 生成コードの格納先パッケージの指定
- パッケージの宣言
syntex = "proto3"; // ライセンスヘッダ
option go_package= "/pb"; // 生成コードの格納先パッケージの指定
package proto; // パッケージの宣言

google.golang.org/protobufモジュール
- 日付や時刻などを扱うにはgoogle.golang.org/protobufモジュールが提供している「Well Known Types」を使用する。
google.golang.org/protobufモジュールの特徴
- Google が公式に定義している よく使われる共通の Protocol Buffers メッセージ型 のこと。これらは、日常的に使われるデータ型を標準化したもので、再利用性や互換性を高めるために作られている。
導入方法
go get google.golang.org/grpc

Messageとは?
- 「データの構造(リクエスト・レスポンスの中身)」を定義するもの。
- gRPCでは、通信でやり取りするリクエストやレスポンスの型 を、
message
キーワードで定義する。
- gRPCでは、通信でやり取りするリクエストやレスポンスの型 を、
message HelloRequest {
string name = 1;
}
message HelloResponse {
string message = 1;
}
Serviceとは?
- gRPCが提供するAPI(関数)群の定義にあたるもの。
- serviceキーワードを使って、リモートで呼び出せる関数(RPCメソッド)を定義する。
メソッドごとに、引数のMessage型と戻り値のMessage型を指定する。
- serviceキーワードを使って、リモートで呼び出せる関数(RPCメソッド)を定義する。
service Greeter {
rpc SayHello (HelloRequest) returns (HelloResponse);
}

コードの生成(プラグインのインストール)
- google.golang.org/protobuf/cmd/protoc-gen-go
- proto2とproto3両方のバージョンに対応したGoコード生成機能を提供する
- google.golang.org/grpc/cmd/protoc-gen-go-grpc
- サービスのGoバインディングを生成する
インストール方法
go install google.golang.org/protobuf/cmd/protoc-gen-go@latest
go install google.golang.org/grpc/cmd/protoc-gen-go-grpc@latest

Goコードの生成
protocを利用してGoコードを生成すると、XXX.pb.goとXXX_grpc.pb.goの2種類のソースコードが生成される。
XXX.pb.go(Message定義)
このファイルには.proto
に定義したmessage
やenum
の構造体が入っている。
- 主な内容
- メッセージ構造体やenumなどの定義
- 生成元のプラグイン
- protoc-gen-go
// .proto
message HelloRequest {
string name = 1;
}
// .go
type HelloRequest struct {
Name string `protobuf:"bytes,1,opt,name=name" json:"name,omitempty"`
...
}
XXX_grpc.pb.go(Service定義)
このファイルには.proto
に定義したservice
の定義から「gRPCサーバーインターフェース」、「クライアント用スタブ」、「サーバー登録関数」が生成される。
- 主な内容
- gRPCサービス定義(インターフェースやクライアント/サーバー)
- 生成元のプラグイン
- protoc-gen-go-grpc
// .proto
service Greeter {
rpc SayHello (HelloRequest) returns (HelloResponse);
}
// .go
// サーバー側が実装すべきインターフェース
type GreeterServer interface {
SayHello(context.Context, *HelloRequest) (*HelloResponse, error)
}
// サーバー登録用関数
func RegisterGreeterServer(s grpc.ServiceRegistrar, srv GreeterServer) {
...
}
// クライアント用構造体
type GreeterClient interface {
SayHello(ctx context.Context, in *HelloRequest, opts ...grpc.CallOption) (*HelloResponse, error)
}

Goコードの生成(エラー対応)
protocコマンド実行時い下記のエラーが出た際の解消方法
エラーログ
protoc --go_out=./ --go-grpc_out=./ proto/*.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.
解消手順
// ① .zshrcにパスを追加
$ vim ~/.zshrc
// ② .zshrcに下記を追加
export PATH="$PATH:$(go env GOPATH)/bin"
// ③ 設定を反映
source ~/.zshrc