1
/
5

gRPCについて学んだこと

Tutorial Advent Calendar 2020の21日目を担当させていただきます、エンジニアの寺田です。リモートワーク中は寒さに負けないようずっと暖房をつけているので電気代が気になる今日このごろです。

Tutorial Advent Calendar 2020 - Adventar
Tutorialとは? チュートリアル(Tutorial)株式会社は、クラウド型RPAツールであるRobotic Crowdを開発・運営する会社です。 詳細はこちら → https://tutorial.co.jp/ # 今回のテーマ 今回のテーマは **Robotic Crowdを支える技術** です。 Robotic Crowdを支える技術であれば、プロダクトに関する技術だけでなく、チーム開発やマーケティングや営業で導入している手法や技術でもOKとします。 # 備考 参加者はTutorialの社員に限
https://adventar.org/calendars/5366

会社のプロダクトのなかで一部gRPCが使われてる箇所があったのですが、そもそもRPCってなんぞやって状態でしたので、勉強してみることにしました。

まずgRPCを勉強しようと思った時に、不明な用語があったのでそれらを整理してから進めることにしました。

RPCとは

まずRPCは、Remote Procedure Call(遠隔手続き呼び出し)の略で、プログラムから別のアドレス空間にあるサブルーチンや手続きを実行することを可能にする技術のこと。

でgRPCは、Google社内で使われていたRPCフレームワークがOSS化され、gRPCと名前がついたもののことだそうです。
ちなみにgRPCのgはGoogleのgではないです。バージョン毎にいろいろg縛りの言葉がついてるようです。
ここに書いてました。
[https://grpc.github.io/grpc/core/md_doc_g_stands_for.html:title]

Protocol Buffersとは

gRPCはデータをProtocol Buffersにシリアライズしてやりとりを行う。
Protocol BuffersもGoogleが開発したフォーマットで、XMLとの比較で、3〜10倍小さく、20〜100倍高速であると主張しているとのこと。

ProtocolBuffersは、protoファイルを作成します。
ファイルをコンパイルすると任意の言語用のコードを自動で作成してくれます。
GoやRubyなど様々な言語に対応しています。
現在はproto3です(いつから3なのか、2との違いは何なのかちゃんと調べてない)

試してみる

公式のチュートリアルの通りにやってみます。
まずサンプルをダウンロードし、ディレクトリ移動

$ git clone -b v1.34.0 https://github.com/grpc/grpc
$ cd grpc/examples/ruby

サーバーを起動する。

$ ruby greeter_server.rb

別のターミナルを開いてクライアントを起動する

$ cd grpc/examples/ruby
$ ruby greeter_client.rb
# 結果が帰ってくる
"Greeting: Hello world"

どういう仕組みかコードを確認してみます。

まずサーバーとして起動したgreeter_server.rbを確認する。

# GreeterServer is simple server that implements the Helloworld Greeter server.
class GreeterServer < Helloworld::Greeter::Service
  # say_hello implements the SayHello rpc method.
  def say_hello(hello_req, _unused_call)
    Helloworld::HelloReply.new(message: "Hello #{hello_req.name}")
  end
end

# main starts an RpcServer that receives requests to GreeterServer at the sample
# server port.
def main
  s = GRPC::RpcServer.new
  s.add_http2_port('0.0.0.0:50051', :this_port_is_insecure)
  s.handle(GreeterServer)
  # Runs the server with SIGHUP, SIGINT and SIGQUIT signal handlers to 
  #   gracefully shutdown.
  # User could also choose to run server via call to run_till_terminated
  s.run_till_terminated_or_interrupted([1, 'int', 'SIGQUIT'])
end

mainでRPCサーバーを0.0.0.0:50051で起動し、ハンドラーにGreeterServerを設定しています。GreeterServesay_helloというメソッドを持ち、Helloworld::HelloReply.new(message: "Hello #{helloreq.name}") を実行します。戻り値として Hello + パラメータで渡されたhelloreqのnameプロパティを返します。(Helloworldモジュールはexamples/ruby/lib/helloworld_services_pb.rbに定義されている。)

クライアント側のコード

def main
  stub = Helloworld::Greeter::Stub.new('localhost:50051', :this_channel_is_insecure)
  user = ARGV.size > 0 ?  ARGV[0] : 'world'
  message = stub.say_hello(Helloworld::HelloRequest.new(name: user)).message
  p "Greeting: #{message}"
end

gRPCのスタブを生成し、say_helloメソッドに"world"を渡しています。こうやってサーバー側のメソッドを呼び出しているんですね。

サーバーは受け取った文字列に"Hello"を付けてクライアントに戻します。
クライアントはサーバから帰ってきた文字列にGreetingを付加して出力しています。クライアントの実行結果が"Greeting: Hello world"となるのはこういう仕組みだったんですね。

所感

チュートリアルをやって軽くコードを読んだだけですが、クライアントからサーバーのメソッドを呼び出すという概要は理解できました。
チュートリアルの最初の最初をやっただけなので、protoファイルの作り方やストリーミング など、もっと学習していこうと思います。

参考にさせていただいた資料

[https://booth.pm/ja/items/1315322:embed:cite]

[https://grpc.io/docs/languages/ruby/basics/:embed:cite]

オートロ株式会社's job postings
4 Likes
4 Likes

Weekly ranking

Show other rankings
Invitation from オートロ株式会社
If this story triggered your interest, have a chat with the team?