概要
Go + gRPCで開発を行う為の環境構築方法を解説します。
環境構築はDockerを利用します。
gRPCの詳しい説明はこの記事では行いません。
想定読者
- Dockerの基礎知識をお持ちの方
- Goの基礎知識をお持ちの方
- Go + gRPCでの開発に興味がある方
サンプルコードをGitHubに登録してあります
以下にサンプルコードを用意してあります。
こちら がDockerfileの中身になります。
以後はこのDockerfileを作り上げるまでに実行した手順を解説しますので、 こちら を見て理解出来る方はこの記事をこれ以上読む必要はありません。
Dockerfileを作るまでの手順
Alpine 3.11系のGoLangイメージをベースにします。
- ホストOS(MacOS Catalina 10.15.2)
- Dockerの実行環境(Docker for Mac 2.1.0.5)
protobufのインストール
gRPCでは初めにインタフェース定義言語 (IDL) でAPIの定義ファイルを作成します。
ここではgRPCでデファクトスタンダードになっている Protocol Buffers を利用出来るようにします。
https://github.com/protocolbuffers/protobuf/releases から最新版ダウンロードを行いインストールを行います。
packageの最新化と関連packageのインストール
packageの最新化とコンパイルに必要なpackageをインストールします。
apk update
apk add git curl build-base autoconf automake libtool
/tmp
に tar.gz
をダウンロードする
curl -L -o /tmp/protobuf.tar.gz https://github.com/protocolbuffers/protobuf/releases/download/v3.11.2/protobuf-cpp-3.11.2.tar.gz
Build、インストールを行う
cd /tmp
で /tmp
に移動します。
tar xvzf protobuf.tar.gz
を実行し .tar.gz
を解凍します。
その後 cd protobuf-3.11.2
で移動します。
以下のコマンドを順番に実行します。
./autogen.sh
./configure
make -j 3
make check
make install
補足ですが make -j
は並行処理を行う事でコンパイルを高速化する為のオプションです。
make -j 3
は3並行処理を行うという意味になります。
お使いの環境の「CPUの数×2」を目安に調整するのが良いと思います。
ちなみに、Build、インストールにはかなりの時間がかかります。
protoc --version
で以下のように表示されれば成功です。
libprotoc 3.11.2
protocのGo用のプラグインをインストール
protocをGoで利用する為にプラグインをインストールします。
go get -u github.com/golang/protobuf/protoc-gen-go
protocによるdocument生成(任意)
こちらは任意ですが、 .proto
からHTML形式等でドキュメントを生成出来るのでインストールしておくと良いでしょう。
go get -u github.com/pseudomuto/protoc-gen-doc/cmd/protoc-gen-doc
protobufの動作確認
こちら に動作確認用のGitリポジトリを用意しました。
プロジェクトルートの pb/
配下に dog.proto
を作成します。
syntax = "proto3";
service Dog {
rpc FindCuteDog (FindCuteDogMessage) returns (FindCuteDogResponse) {}
}
message FindCuteDogMessage {
string DogId = 1;
}
message FindCuteDogResponse {
string name = 1;
string kind = 2;
}
プロジェクトルート(私のサンプルプロジェクトだと /go/app
)で以下のコマンドを実行します。
protoc --go_out=plugins=grpc:. pb/dog.proto
そうすると pb/dog.pb.go
というファイルが作成されているかと思います。
以下のようなファイルです。(内容を一部載せています。)
// Code generated by protoc-gen-go. DO NOT EDIT.
// source: pb/dog.proto
package dog
import (
context "context"
fmt "fmt"
proto "github.com/golang/protobuf/proto"
grpc "google.golang.org/grpc"
codes "google.golang.org/grpc/codes"
status "google.golang.org/grpc/status"
math "math"
)
// Reference imports to suppress errors if they are not otherwise used.
var _ = proto.Marshal
var _ = fmt.Errorf
var _ = math.Inf
// This is a compile-time assertion to ensure that this generated file
// is compatible with the proto package it is being compiled against.
// A compilation error at this line likely means your copy of the
// proto package needs to be updated.
const _ = proto.ProtoPackageIsVersion3 // please upgrade the proto package
type FindCuteDogMessage struct {
DogId string `protobuf:"bytes,1,opt,name=DogId,proto3" json:"DogId,omitempty"`
XXX_NoUnkeyedLiteral struct{} `json:"-"`
XXX_unrecognized []byte `json:"-"`
XXX_sizecache int32 `json:"-"`
}
func (m *FindCuteDogMessage) Reset() { *m = FindCuteDogMessage{} }
func (m *FindCuteDogMessage) String() string { return proto.CompactTextString(m) }
func (*FindCuteDogMessage) ProtoMessage() {}
func (*FindCuteDogMessage) Descriptor() ([]byte, []int) {
return fileDescriptor_993586c250cd4a03, []int{0}
}
// 以下略
ここまでの手順でGo + gRPCで開発出来る環境が整いました。
最終的なDockerfileを載せておきます。(こちら と同様の内容です)
FROM golang:1.13-alpine3.11 as build
WORKDIR /tmp
ENV PROTOBUF_VERSION 3.11.2
ENV PROTOBUF_URL https://github.com/protocolbuffers/protobuf/releases/download/v$PROTOBUF_VERSION/protobuf-cpp-$PROTOBUF_VERSION.tar.gz
RUN set -eux && \
apk update && \
apk add --no-cache git curl build-base autoconf automake libtool && \
curl -L -o /tmp/protobuf.tar.gz $PROTOBUF_URL && \
tar xvzf protobuf.tar.gz
WORKDIR /tmp/protobuf-$PROTOBUF_VERSION
RUN set -eux && \
./autogen.sh && \
./configure && \
make -j 3 && \
make install && \
go get -u github.com/golang/protobuf/protoc-gen-go && \
go get -u github.com/pseudomuto/protoc-gen-doc/cmd/protoc-gen-doc
WORKDIR /go/app
COPY . .
RUN set -eux && \
go build -o golang-grpc-server && \
go get gopkg.in/urfave/cli.v2@master && \
go get github.com/oxequa/realize && \
go get -u github.com/go-delve/delve/cmd/dlv && \
go build -o /go/bin/dlv github.com/go-delve/delve/cmd/dlv
FROM alpine:3.11
WORKDIR /app
COPY --from=build /go/app/golang-grpc-server .
RUN set -x && \
addgroup go && \
adduser -D -G go go && \
chown -R go:go /app/golang-grpc-server
CMD ["./golang-grpc-server"]
以前 Docker上のGo製Webアプリケーションをリモートデバッグする という記事を書きましたが、この記事で紹介しているデバッガー等のインストールもこの Dockerfile
で行っています。
protocによるdocument生成
こちらのプロジェクト を例に説明します。
docs
配下にHTML形式のドキュメントを生成する為には下記のコマンドを実行します。
protoc --doc_out=html,index.html:./docs pb/*.proto
結果として docs/index.html
が出力されます。
見た目はこんな感じです。

おまけ gRPCサーバーの動作確認(grpc_cli を利用)
gRPCはcurl等で手軽に動作確認が出来ませんでしたが、gRPC command line tool を利用すると動作確認が簡単です。
Mac上にインストールします。
brew install gflags
brew tap grpc/grpc
brew install grpc
which grpc_cli
を実行して /usr/local/bin/grpc_cli
等が表示されればインストール出来ています。
grpc_cliの簡単な使い方
以下でServiceの内容を取得します。
grpc_cli ls localhost:9998
以下のようにgRPCサーバーの内容が表示されます。
Cat
grpc.reflection.v1alpha.ServerReflection
次のようにメソッドを指定するとそのインターフェースを確認出来ます。
grpc_cli ls localhost:9998 Cat.FindCuteCat -l
これらのgRPCサーバーの情報を取得する為にはgRPCサーバー側で reflection.Register
が実行されている必要があります。
詳しくは こちらのコード を確認して下さい。
実際にgRPCのメソッドを呼び出す際は下記のように実行します。
grpc_cli call localhost:9998 Cat.FindCuteCat 'catId: "moko"'
おわり
以上がGo + gRPCでの開発環境構築方法です。
最近はマイクロサービスでの開発が多いので、Go + gRPCという組み合わせの採用例が増えているように感じます。
この記事が少しでもお役に立てたら幸いです。
今回の記事を書く為に以下の記事を参考にさせて頂きました。