マイクロサービスアーキテクチャを使用する場合、サービス間の通信のオーバーヘッドがしばしば重大な問題になることを知っている可能性が高く、この問題に遭遇した場合、
Protobuf上のRPCフレームワークの
いずれか 、たとえばGoogleの
gRPC Peter Bourgonによる
Go-Kitなど。 それが何であるか、それをどのように使用するかを説明することは意味がありません。すべてが私の前に非常によく説明されています。 私自身、プロジェクトでgRPCを積極的に使用していますが、ここで
Twichはprotobuf
Twirpの実装をリリースすることにし
ました 。 なぜそれが必要なのか、それがどのように異なるのか疑問に思っているなら、猫の下に行ってください。
まず、TwichがProtoBufの独自バージョンをリリースした理由を見てみましょう。
- HTTP 1.1のサポートの欠如。 gRPSは、HTTPトレーラーと全二重ストリームに依存しています。 TwirpはHTTP 1.1とHTTP / 2の両方をサポートします。これは、AWS Elastic Load Balancerを含む多数のロードバランサー(ハードウェアとソフトウェアの両方)がHTTP 1.1のみをサポートするため、非常に重要です。 ただし、gRPCとは異なり、TwirpはストリーミングRPCをサポートしません。これは、APIが要求/応答に基づいて構築されており、必須ではない場合です。
- grpc-goライブラリの実装の複雑さ。 このライブラリには、標準ライブラリとは独立したHTTP / 2の完全な実装が含まれているため、発生するエラーの理解と分析が困難になります。
- GRPCバージョンの互換性。 gRPCはかなり複雑であるため、Goで生成されたコードは非常にシンプルで、すべてのリクエストはgrpc-goにリダイレクトされます。 この接続により、クライアントはサーバーと同じバージョンを使用せざるを得なくなります。 また、多数の顧客がいて、サービスが相互にやり取りする場合、顧客間のバージョンは同一である必要があります。 これにより、マイクロサービスの展開と展開が困難になることは明らかです。
- Twitchはまた、grpc-goには特定のバージョンのprotobuf-github.com/golang/protobufが必要であることを示しています。 しかし、私にとっては、protobufにはバージョンv1.0.0のリリースが1つしかなく、これはgrpc-goのすべてのバージョンで使用されているため、この問題は大げさなようです。
- gRPCはバイナリメッセージ形式のみをサポートし、メッセージスニッフィングの分析は非常に困難です。 Twirpは、protobuf形式のバイナリメッセージ形式とJSON形式の非バイナリメッセージ形式の両方をサポートしています。 これにより、JSONを使用した通常のHTTPリクエストを介してサービスとやり取りしたい場合など、利点が得られます。
ご覧のとおり、TwichがProtobufの実装を記述することにした主な理由は、単純さです。
次に、このライブラリの使用方法を見てみましょう。
Goで開発環境を既に設定している場合は、次のパッケージをインストールする必要があります
go get github.com/twitchtv/twirp/protoc-gen-twirp go get github.com/golang/protobuf/protoc-gen-go
たとえば、パラメーターとして渡された値をインクリメントする単純なサービスを作成します。
syntax = "proto3"; service Service { rpc Increment(Request) returns (Response); } message Request { int32 valueToIncrement = 1;
次のコマンドを実行して、クライアントのコードを生成します
protoc --proto_path=$GOPATH/src:. --twirp_out=. --go_out=. ./paperclips.proto
その結果、2つのファイルが作成されます。
- Increment.pb.go-メッセージのコード生成が含まれています
- Increment.twirp.go-サービスのインターフェースと機能が含まれています
次に、サービスの実装を追加します
package main import ( "fmt" "log" "net/http" "context" pb "TwirpSample/Server/Twirp" )
これで、
go run main.goコマンドを使用してクライアントを起動すると、HTTP経由でサービスにアクセスできます。
curl --request "POST" \ --location "http://localhost:6666/Service/Increment" \ --header "Content-Type:application/json" \ --data '{ValueToIncrement: 0}' \ --verbose Output: {"IncrementedValue":1}
またはバイナリ形式で
package main import ( "fmt" rpc "TwirpSample/Server/Twirp" "net/http" "context" ) func main() { fmt.Println("Twirp Client Example.") client := rpc.NewServiceProtobufClient("http://localhost:6666", &http.Client{}) v, err := client.Increment(context.Background(), &rpc.Request{ValueToIncrement: 11}) if err != nil { fmt.Println(err.Error()) } fmt.Printf("Value: %d", v.IncrementedValue) } Output: Twirp Client Example. Value: 11
一般に、フレームワーク自体のアプローチはgRPCとほとんど同じですが、実装が簡単で、同時にHTTP 1.1をサポートしています。 私の意見では、その適用性は、HTTPを介してUIと、Protobufを介してサービス間で同時に対話することを計画しているRPCサービスが必要な場合です。
参照: