0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

gRPCについて公式のサンプルコードから勉強

Last updated at Posted at 2023-05-07

初めに

記事の内容について

  • gRPCとはを公式のサンプル(Python)を読んで理解しようという内容
  • 筆者の勉強のために残している記事のため、内容の正確性は保証しません

なぜgRPCについて、Pythonで勉強しているのか

  • プライベートで何かを作るのに、マイクロサービスアーキテクチャを採用したい→RPCを使ってみよう
    • RPCの中でも、比較的多言語でライブラリが用意されているgRPCが良さそう→gRPCを使おう
  • せっかくのプライベートなので触ったことのない言語にしたい
    • Python?Go?Ruby?→とりあえず、Pythonでやってみるか

筆者について

  • 社会人4年目のバックエンドエンジニア
    • 周りと比べてほんの少し、インフラ(クラウド)に詳しいくらい
  • Java/SpringBootでの開発経験のみ
    • PythonはHello Worldを書いた?ことがある程度(なんかAI分野に強いんでしょ?程度)
  • 趣味:コーヒーと自作キーボード
    • コーヒーは自宅焙煎したり、自宅に7万くらいのコーヒーサーバーを置いていたりするレベル
    • 自作キーボードは絶賛設計中。この記事も自作キーボードを使用して執筆

環境

  • 端末:MacBookAir M1
  • Python:3.10.6
  • pip:23.1.1(多分Pythonに付いてきてるバージョンそのまま)

今回の学習にあたり参考にしたページ

gRPCとは

gじゃないRPCとは?

  • Remote Procedure Call(遠隔手続き呼び出し)の頭文字をとったもの
  • 外部から関数を呼び出す的な感じと理解
  • マイクロサービス化した際に、サービス間通信とかで使われる
  • JSON-RPCやgRPCといったようにいろんな種類がある

gRPC

  • Googleが開発したRPC
  • データをバイナリでやり取りする
  • HTTP/2とProtocol Buffersを使用
    • Protocol Buffersはデータのシリアライズの仕様兼、ライブラリ。ここ深掘りするともう一つ記事書けそうなくらい、中身深そう。
    • シリアライズとは、ざっくりいうと実行中に生成されたオブジェクトをバイナリorテキストデータに変換すること。
  • なんか高速。らしい。

環境構築

環境の準備

Prerequisites
・Python 3.7 or higher
・pip version 9.0.1 or higher

とのこと、筆者の環境は特に更新は不要だった

各種インストール

  • gRPCライブラリ(grpcio)のインストール
    $ pip install grpcio
    
    PythonでgRPC Server/Clientを構築するためのライブラリ
  • gRPCツール(grpcio-tools)のインストール
    $ pip install grpcio-tools
    
    gRPC Server/Clientを作るための便利ツールだと思われる

サンプルの実行

サンプルのダウンロード

gRPC公式さんの方でサンプルコードを準備していくれているっぽい

# Clone the repository to get the example code:
$ git clone -b v1.54.0 --depth 1 --shallow-submodules https://github.com/grpc/grpc
# Navigate to the "hello, world" Python example:
$ cd grpc/examples/python/helloworld

ちょっと気になったので確認してみたが、他にも下記言語のサンプルが入っていた

  • java(android)
  • C++
  • node
  • Objective-C
  • PHP
  • Ruby

他にもprotosというディレクトリがあるが、こちらについては後述

サンプルコードの実行

  • gRPCサーバの起動
    $ python greeter_server.py 
    Server started, listening on 50051
    
  • gRPCクライアントの起動(↑とは別terminal)
    $ python greeter_client.py 
    Will try to greet world ...
    Greeter client received: Hello, you!
    

それっぽい何かが起きた

サンプルコードへの理解

執筆時のソースコード
各ファイルの内容は{行番号}:{説明}の形式で内容を記述

greeter_server.pyの内容

  • 24~27:Greeterクラスの実装
    helloworld_pb2_grpc.pyのGreeterServicerクラスを継承
    • 26~27:SeyHelloメソッドのオーバーライド
      HelloReplyにmessageを設定
  • 30~37: Serveメソッドの定義
    サーバの起動メソッド
    • 31:サーバがListenするポート番号を変数として定義
    • 32:worker数10でserverインスタンスを作成
      • python/grpcのworkerの概念に自信はないが、おそらく10リクエストまでは並列でさばけると思われる
    • 33:24行目で実装したGreeterクラスを32行目で作成したserverインスタンスに登録
    • 34:serverインスタンスにポートを登録
    • 35:サーバ起動
    • 36:サーバが起動した旨のログを表示
    • 37:sigtermが送られるまで待機?
    • 40~42:python起動時の制御。Loggingの設定と、サーバ起動メソッドの呼び出し

greeter_client.pyの内容

  • greeter_server.pyと大して変わらないので割愛

helloworld_pb2.pyの内容

おそらくgrpc-toolsで自動生成されるファイル

  • 11:ProtocolBuffers用DBの初期化
  • 16:helloworld.protoを基に、Descriptorを定義
    • Descriptorとは、gRPCでやり取りするバイナリデータの型情報を持つもの。gRPCでやり取りしたデータをプログラムで受け取るために使われる(はず)
  • 18,19:builderの設定、16行目で生成したDESCRIPTORをかませている
  • 20~30:シリアライズ方法の設定をしている(多分。何やってるか分かっている自信はないが、書かれている内容的そうだろうと思っている。)

helloworld.protoの内容

  • そもそもprotoファイルとは?
    • インターフェース記述ファイル
    • ProtocolBuffersでやり取りする方法、やり取りするデータについて定義
      • こういうデータを使用して、この関数呼び出したら、こいつ返すよ。が書かれたファイル。
  • 15:version指定
  • 17~20:各言語向けoption設定。
    • 深掘りしたいが、今回はPythonなので、一旦ノータッチ。いつかPythonのoptionを使用したり、JavaでgRPCを使う時が来たら記事化したい
  • 22:package定義
    • 同名のgRPCサービスを定義できるようにするため、パッケージの概念がある
  • 25~30:RPCで使用するサービスのイターフェース定義
    • 27:SayHello RPCを定義。HelloRequestを受け取り、HelloReplyを返却する
    • 29:SayHelloStream RPCを定義。HelloRequestStreamを受け取り、StreamでHelloReplyを返却する
  • 33~35:HelloRequestメッセージを定義
    • 34:要素として、string型のnameのみを持つ。
  • 38~40
    • 39:要素として、string型のmessageのみを持つ。

helloworld_pb2_grpc.pyの内容

おそらくgrpc-toolsで自動生成されるファイル

  • 8~22:GreeterStubクラスの定義
    クライアント側で使用するクラス
    • 12~22:コンストラクタ
      gRPCメソッドの設定
      grpc.channel.unary_unary(method,request_serializer,response_serializer)を使用
      helloworld.protoで定義した/helloworld.Greeter/SayHelloという名前のgRPCメソッドを定義python側に定義
      requestのSerializerにhelloworld_pb2.pyで定義されたSerializerを設定
      reponseのSerializerも同様
      • unary_unaryとは?
        unaryは単一を意味しているため、一つのメソッド呼び出しに対し、一つの値を返却するrpc関数を定義している(と理解)
  • 25~34:GreeterServicerクラスの定義
    サーバ側で使用するクラス
    • 29~34:SayHelloメソッドの定義
      実装されていないメソッドとして、定義し、実装されない場合はErrorを返す
  • 37~47:add_GreeterServicer_to_serverメソッドの定義
    • 38:rpc_method_handlerへの登録
      SayHelloという名前でunary_unary_rpc_handlerを登録。やっていることは12~22行目とほぼ一緒
    • 45:generic_handlerへのrpc_method_handlerの登録
      helloworld.protoで定義した、Greeterサービスに38行目でrpc_method_handlerを紐付け
    • 46:serverにrpc_method_handlerを登録
  • 51~70:Greeterクラスの定義
    EXPERIMENTAL APIとのこと。実際には使用せず、上記クラスたちを用いて、クライアントを実装することが望ましいと思われる。
    • スタティックなSayHelloメソッドが用意されている。が、使うのは大変そう。
    • ここでは割愛

次回へ

実際に自分でgRPCサーバとクライアントを作ってみたい

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?