Open2
grpc

todo
- 目次作成
-
https://www.notion.so/grpc-1ea031b7ac3d8008ba5ec1f2836bccca
- まとめる
- work/tracking_praceいじる
protoファイルが設計図
=> コマンドで生成されるのは interfaceでclient と serverは自分で実装する必要あり
・port
50051がデフォルト
50052~からが複数サービス
443はロードバランサー越しで通信
・どんな時に使う
内部通信、パフォーマンス
・サンプル
- 外部とのやりとり => go api
- 内部通信
- 作業
- grpc とrest aoiは別々に起動

grpc
- マイクロサービスアーキテクチャーで利用されるケースが多い
- 双方向通信
- 処理が早いなど
概念
- サービス
- Procedure(関数)をメソッド、そしてそのメソッドをいくつかまとめて一括りにしたものをサービス
- メソッド
コンポーネント
.protoファイル
- 設計図
xx.pb.go
- リクエストとレスポンスを定義したコード
// 生成されたGoの構造体
type HelloRequest struct {
state protoimpl.MessageState
sizeCache protoimpl.SizeCache
unknownFields protoimpl.UnknownFields
Name string `protobuf:"bytes,1,opt,name=name,proto3" json:"name,omitempty"`
}
type HelloResponse struct {
state protoimpl.MessageState
sizeCache protoimpl.SizeCache
unknownFields protoimpl.UnknownFields
Message string `protobuf:"bytes,1,opt,name=message,proto3" json:"message,omitempty"`
}
xx_grpc.pb.go
- サービス部分のコード
- 複数のメソッド(プロシージャー: hello関数のような)をまとめたもの
-
RegisterGreetingServiceServer
などが作成
// 生成されたGoのコード
type GreetingServiceServer interface {
// サービスが持つメソッドの定義
Hello(context.Context, *HelloRequest) (*HelloResponse, error)
mustEmbedUnimplementedGreetingServiceServer()
}
// クライアント
func NewGreetingServiceClient(cc grpc.ClientConnInterface) GreetingServiceClient {
return &greetingServiceClient{cc}
}
// server
func RegisterGreetingServiceServer(s grpc.ServiceRegistrar, srv GreetingServiceServer) {
// If the following call pancis, it indicates UnimplementedGreetingServiceServer was
// embedded by pointer and is nil. This will cause panics if an
// unimplemented method is ever invoked, so we test this at initialization
// time to prevent it from happening at runtime later due to I/O.
if t, ok := srv.(interface{ testEmbeddedByValue() }); ok {
t.testEmbeddedByValue()
}
s.RegisterService(&GreetingService_ServiceDesc, srv)
}
severを作成する
- cmd/server/main.go
- _grpc.pb.goで生成された
RegisterGreetingServiceServer
などを利用 - サーバー起動
- _grpc.pb.goで生成された
port := 8080
listener, err := net.Listen("tcp", fmt.Sprintf(":%d", port))
if err != nil {
panic(err)
}
// 2. gRPCサーバーを作成 これはパッケージ
s := grpc.NewServer()
// 3 GreetingService を sを通じて登録
hellopb.RegisterGreetingServiceServer(s, NewMyServer())
reflection.Register(s)
client
- _groc.pb.goで生成された、
NewGreetingServiceClient
で接続
fmt.Println("start gRPC Client.")
// 1. 標準入力から文字列を受け取るスキャナを用意
scanner = bufio.NewScanner(os.Stdin)
// 2. gRPCサーバーとのコネクションを確立 (バックエンドとコネクション作るんだ)
address := "localhost:8080"
conn, err := grpc.Dial(
address,
grpc.WithTransportCredentials(insecure.NewCredentials()),
grpc.WithBlock(),
)
if err != nil {
log.Fatal("Connection failed.")
return
}
defer conn.Close()
// 3. gRPCクライアントを生成
client = hellopb.NewGreetingServiceClient(conn)
- _groc.pb.goで生成された、メソッドを利用できる
type GreetingServiceClient interface {
// サービスが持つメソッドの定義
Hello(ctx context.Context, in *HelloRequest, opts ...grpc.CallOption) (*HelloResponse, error)
}
修正方法
- .protoのInterfacewを変更する
// protoのバージョンの宣言
syntax = "proto3";
// protoファイルから自動生成させるGoのコードの置き先
// (詳細は4章にて)
option go_package = "pkg/grpc";
// packageの宣言
package myapp;
// サービスの定義
service GreetingService {
// サービスが持つメソッドの定義
rpc Hello (HelloRequest) returns (HelloResponse);
}
// 型の定義
message HelloRequest {
string name = 1;
}
message HelloResponse {
string message = 1;
}
- protocコマンドで,変更を反映する
protoc --go_out=../pkg/grpc --go_opt=paths=source_relative \
--go-grpc_out=../pkg/grpc --go-grpc_opt=paths=source_relative \
hello.proto
動作確認 gRPCurl
$ brew install grpcurl
$ which grpcurl
[パスが表示されればインストール成功]
// サービス一覧
grpcurl -plaintext localhost:8080 list
// あるサービスのメソッド一覧
grpcurl -plaintext localhost:8080 list myapp.GreetingService
// メソッド呼び出し
$ grpcurl -plaintext -d '{"name": "hsaki"}' localhost:8080 myapp.GreetingService.Hello
ステータスコード
17種類
ミドルウェア(インターセプタ)
- クライント・バックエンド両方
参考
作業
- ツール入れる
brew install protobuf
go install google.golang.org/protobuf/cmd/protoc-gen-go@latest
go install google.golang.org/grpc/cmd/protoc-gen-go-grpc@latest
- composeでサーバーをセット
FROM golang:1.24-alpine AS go
WORKDIR /app
COPY go.mod go.sum ./
RUN go mod download
COPY
. .
RUN go build -o grpc-server ./grpcserver/main.go
EXPOSE 50051
CMD ["/app/grpc-server"]
grpc_server:
build:
context: .
dockerfile: ./grpcserver/Dockerfile
env_file:
- .env
-
ディレクトリ作成
- grpcserver
- エンドポイント
- server
- エンドポイント
- gateway(内部通信を表現したい場合)
- pb.go
- client.go
- grpcserver
-
コード生成
protoc \
--go_out=paths=source_relative:gateway/coin \
--go-grpc_out=paths=source_relative:gateway/coin \
proto/coin.proto