フラミナル

考え方や調べたことを書き殴ります。IT技術系記事多め

【手順あり】CentoOS7にgrpcurlをいれてコマンドの確認をしてみる

f:id:lirlia:20200417164300p:plain

grpcurlはgRPCサーバに対してcurlのように通信が行えるクライアントツールです。

このように利用できます。

grpcurl 192.168.0.1 helloworld.Greeter/helloworld

この記事ではgrpcurlのインストールから実際に叩いてみるところまでをご紹介します。またこの記事で紹介するコードはいかに格納しています。

前提

  • CentOS7の環境であること
  • pipがインストールされていること

準備

mkdir ~/grpctest/
cd ~/grpctest

ライブラリのインストール

pip install grpcio-reflection grpcio grpcio-tools

サーバ用のコードの配置

vim greeter_server.py

以下をコピー。

from concurrent import futures
import logging
  
import grpc
from grpc_reflection.v1alpha import reflection
  
import helloworld_pb2
import helloworld_pb2_grpc
  
class Greeter(helloworld_pb2_grpc.GreeterServicer):
  
    def SayHello(self, request, context):
        return helloworld_pb2.HelloReply(message="Hello, %s!" %request.name)
  
    def SayHelloAgain(self, request, context):
        return helloworld_pb2.HelloReply(message='Hello again, %s!' % request.name)
  
    def CalcBMI(self, request, context):
        height = float(request.height) / 100
        weight = float(request.weight)
        bmi = weight / (height ** 2)
        return helloworld_pb2.BMIReply(bmi = bmi)
  
def serve():
    server = grpc.server(futures.ThreadPoolExecutor(max_workers=10))
    helloworld_pb2_grpc.add_GreeterServicer_to_server(Greeter(), server)
  
    SERVICE_NAMES = (
        helloworld_pb2.DESCRIPTOR.services_by_name['Greeter'].full_name,
        reflection.SERVICE_NAME,
    )
    reflection.enable_server_reflection(SERVICE_NAMES, server)
  
    server.add_insecure_port('[::]:50051')
    server.start()
    server.wait_for_termination()
  
if __name__ == '__main__':
    logging.basicConfig()
    serve()

protoファイルの配置

vim helloworld.proto

以下をコピペ

syntax = "proto3";
  
option java_multiple_files = true;
option java_package = "io.grpc.examples.helloworld";
option java_outer_classname = "HelloWorldProto";
option objc_class_prefix = "HLW";
  
package helloworld;
  
// The greeting service definition.
service Greeter {
  // Sends a greeting
  rpc CalcBMI (BMIRequest) returns (BMIReply) {}
  rpc SayHello (HelloRequest) returns (HelloReply) {}
  rpc SayHelloAgain (HelloRequest) returns (HelloReply) {}
}
  
message BMIRequest {
  int32 height = 1;
  int32 weight = 2;
}
  
message BMIReply {
  float bmi = 1;
}
  
// The request message containing the user's name.
message HelloRequest {
  string name = 1;
}
  
// The response message containing the greetings
message HelloReply {
  string message = 1;
}

protoファイルからコードの生成

python -m grpc_tools.protoc -I. --python_out=. --grpc_python_out=. helloworld.proto

ここまで実行するとこのようになります。

[root@master grpctest]# ls -1
greeter_server.py
helloworld.proto
helloworld_pb2.py
helloworld_pb2_grpc.py

grpcurlのインストール

こちらの記事で紹介しています。

blog.framinal.life

grpcサーバーの起動

python greeter_server.py

localhost:50051でgRPCサーバがListenします。

grpcurlでサーバに疎通確認

別のターミナルを開いてgrpcurl -plaintext localhost:50051 describeを叩きましょう。

-plaintextはTLSを使用していない場合に使うオプションです。これがないとFailed to dial target host "localhost:50051": tls: first record does not look like a TLS handshakeと怒られてしまいます。

正しく接続できれば先ほど起動したサーバに定義されているサービスが表示されます。

describeコマンド

登録されているサービスの詳細情報

client# grpcurl -plaintext localhost:50051 describe
grpc.reflection.v1alpha.ServerReflection is a service:
service ServerReflection {
  rpc ServerReflectionInfo ( stream .grpc.reflection.v1alpha.ServerReflectionRequest ) returns ( stream .grpc.reflection.v1alpha.ServerReflectionResponse );
}
helloworld.Greeter is a service:
service Greeter {
  rpc CalcBMI ( .helloworld.BMIRequest ) returns ( .helloworld.BMIReply );
  rpc SayHello ( .helloworld.HelloRequest ) returns ( .helloworld.HelloReply );
  rpc SayHelloAgain ( .helloworld.HelloRequest ) returns ( .helloworld.HelloReply );
}

登録されているメソッドの詳細情報

client# grpcurl -plaintext 0.0.0.0:50051 describe helloworld.Greeter.CalcBMIhelloworld.Greeter.CalcBMI is a method:
rpc CalcBMI ( .helloworld.BMIRequest ) returns ( .helloworld.BMIReply );

listコマンド

登録されているサービスの一覧

client# grpcurl -plaintext 0.0.0.0:50051 list
grpc.reflection.v1alpha.ServerReflection
helloworld.Greeter

サービスに含まれるメソッドの一覧

client# grpcurl -plaintext 0.0.0.0:50051 list helloworld.Greeter
helloworld.Greeter.CalcBMI
helloworld.Greeter.SayHello
helloworld.Greeter.SayHelloAgain

メソッドを叩いてみる

SayHelloメソッドの場合

client# grpcurl -plaintext -d '{"name": "taro" }' 0.0.0.0:50051 helloworld.Greeter.SayHello
{
  "message": "Hello, taro!"
}

SayHelloAgainメソッドの場合

client# grpcurl -plaintext -d '{"name": "taro" }' 0.0.0.0:50051 helloworld.Greeter.SayHelloAgain
{
  "message": "Hello again, taro!"
}

CalcBMIメソッドの場合

client# grpcurl -plaintext -d '{"height": 160, "weight": 60 }' 0.0.0.0:50051 helloworld.Greeter.CalcBMI
{
  "bmi": 23.4375
}

余談ですがcurlコマンドのようにパスで(helloworld.Greeter/CalcBMI)アクセスすることができます。

client# grpcurl -plaintext -d '{"height": 160, "weight": 60 }' 0.0.0.0:50051 helloworld.Greeter/CalcBMI
{
  "bmi": 23.4375
}