📲

Go言語を使った gRPC解説⚡️

2025/02/20に公開

gRPC は、Google が開発した高速・軽量なRPC(Remote Procedure Call)フレームワークで、マイクロサービス間の通信に最適です。
Go言語との相性が良く、効率的なサーバー・クライアントの通信を実現できます。


gRPCとは?

gRPC(gRPC Remote Procedure Call) は、以下の特徴を持つ通信フレームワークです。

  • Protocol Buffers(プロトコルバッファ) を使用して、データのシリアライズを高速かつコンパクトに行う。
  • HTTP/2 を採用しているため、双方向ストリーミングや高効率な通信が可能。
  • 多言語対応で、Go, Python, Java, C++ などで実装されたサービス間の通信が可能。

gRPC のメリット

  • 高速で軽量な通信が可能
  • ストリーミング通信に対応
  • 型安全な通信(Protocol Buffersを使用)

gRPC の基本構成

gRPC には以下の構成要素があります。

  • Protocol Buffers(.proto ファイル):通信のインターフェースを定義する。
  • Server(サーバー):サービスを提供する側。
  • Client(クライアント):サービスを呼び出す側。

実装準備

必要なツールのインストール

  1. Protocol Buffers Compiler (protoc)
brew install protobuf  # macOS の場合
  1. Go 用 gRPC プラグイン
go install google.golang.org/protobuf/cmd/protoc-gen-go@latest
go install google.golang.org/grpc/cmd/protoc-gen-go-grpc@latest
  1. 環境変数の設定
export PATH="$PATH:$(go env GOPATH)/bin"

gRPC の実装

1. .proto ファイルの作成

まず、通信のインターフェースを定義するための .proto ファイルを作成します。

example.proto

syntax = "proto3";
package example;

// サービスの定義
service Greeter {
    // RPC メソッドの定義
    rpc SayHello (HelloRequest) returns (HelloResponse) {}
}

// リクエストメッセージの定義
message HelloRequest {
    string name = 1;
}

// レスポンスメッセージの定義
message HelloResponse {
    string message = 1;
}

2. gRPC のコード生成

以下のコマンドを実行して、Go 用の gRPC コードを生成します。

protoc --go_out=. --go-grpc_out=. example.proto

以下の 2 つのファイルが生成されます。

  • example.pb.go:Protocol Buffers のコード
  • example_grpc.pb.go:gRPC のコード

3. サーバーの実装

server.go

package main

import (
    "context"
    "fmt"
    "log"
    "net"

    "google.golang.org/grpc"
    pb "example"
)

// サーバーの構造体
type server struct {
    pb.UnimplementedGreeterServer
}

// SayHello メソッドの実装
func (s *server) SayHello(ctx context.Context, req *pb.HelloRequest) (*pb.HelloResponse, error) {
    message := "Hello, " + req.Name
    return &pb.HelloResponse{Message: message}, nil
}

func main() {
    lis, err := net.Listen("tcp", ":50051")
    if err != nil {
        log.Fatalf("failed to listen: %v", err)
    }
    s := grpc.NewServer()
    pb.RegisterGreeterServer(s, &server{})
    fmt.Println("Server is running on port 50051")
    if err := s.Serve(lis); err != nil {
        log.Fatalf("failed to serve: %v", err)
    }
}

4. クライアントの実装

client.go

package main

import (
    "context"
    "fmt"
    "log"
    "time"

    "google.golang.org/grpc"
    pb "example"
)

func main() {
    conn, err := grpc.Dial("localhost:50051", grpc.WithInsecure())
    if err != nil {
        log.Fatalf("did not connect: %v", err)
    }
    defer conn.Close()

    c := pb.NewGreeterClient(conn)
    ctx, cancel := context.WithTimeout(context.Background(), time.Second)
    defer cancel()

    r, err := c.SayHello(ctx, &pb.HelloRequest{Name: "Gopher"})
    if err != nil {
        log.Fatalf("could not greet: %v", err)
    }
    fmt.Println("Greeting: ", r.Message)
}

実行方法

  1. サーバーの起動
go run server.go
  1. クライアントの実行

別のターミナルを開いて、以下のコマンドを実行します。

go run client.go

実行結果

Server is running on port 50051
Greeting: Hello, Gopher
  • サーバーがポート 50051 で待ち受け。
  • クライアントがリクエストを送信し、サーバーからのレスポンスを受け取る。

まとめ

項目 説明
gRPC 高速・軽量な RPC フレームワーク
Protocol Buffers 型安全で高速なシリアライズ形式
メリット 高速通信、ストリーミング対応、型安全な通信

gRPC を使用することで、効率的なマイクロサービス間通信を実現できます。
Go言語初めて間もないけど切実に慣れていきたい...

Discussion