gRPCとは?
仕事関係で、gRPC技術と関わっていたので、調べてみることにしました。
ググってみると、
「gRPCは、Googleが開発したオープンソースの高性能なリモートプロシージャコール(RPC)フレームワークです。」らしいです。
えーと、ぴんとこないので、ChatGPTに簡単に解析をお願いしました。
質問: ちょっとわかりづらいので、小学生でもわかるようなケースを例をあげて欲しいです。
回答: 以下は回答です。
もちろんです。gRPCを小学生に説明するなら、こんな感じでしょうか:
想像してみてください。あなたは大きな学校の一部で、たくさんのクラスがあります。各クラスは、特別なタスク(仕事)を持っています。例えば、一つのクラスは図画を描くことが得意で、もう一つのクラスは音楽を作ることが得意です。
でも、時々、あるクラスが別のクラスの助けを必要とすることがあります。音楽クラスが絵を描くことが必要になった時、どうすればいいでしょう?そこで、gRPCというシステムが活躍します。
gRPCは、学校の中でメッセージを送るための超速いポストマンのようなものです。音楽クラスが絵を描いてほしい時、gRPCポストマンにメッセージを渡します。そして、gRPCポストマンはそのメッセージを超速で図画クラスに届けます。図画クラスはそのメッセージを受>け取り、必要な絵を描いて、またgRPCポストマンを使って音楽クラスに戻します。
このシステムが素晴らしいのは、どのクラスも特別な言葉(プログラミング言語)を使って話すことができ、gRPCポストマンはそれら全ての言葉を理解して、クラス間で正確にメッセージを届けることができる点です。
更に、gRPCポストマンはとても安全にメッセージを運ぶことができるので、誰かにメッセージが盗まれる心配はありません。そして、一度にたくさんのメッセージを運ぶことができるので、とても効率的です。
だから、学校(システム)がたくさんのクラス(サービス)で成り立っていて、お互いに助け合いながら素晴らしいプロジェクト(アプリケーション)を作りたい時、gRPCはとても役に立ちます。
なるほど。
理解できましたね。 ありがとうー ChatGPT.
言葉レベルで理解しておくだけでは、もの足りないので、サンプルを作って動かしてみたいと思いました。
簡単なサンプルを作って、もっと深めたいですね。
実現したいサンプル
gRPCを使用して簡単なサンプルコードを作成するためには、まずプロトコルバッファ(protobuf)ファイルを定義する必要があります。ここでは、簡単な「挨拶」サービスを作成します。このサービスでは、クライアントがサーバーに名前を送信し、サーバーが「Hello, [名前]!」と応答するというものです。
流れ
- Protobufファイルの定義
- サーバー側のコードの作成
- クライアント側のコードの作成
Step 1: Protobufファイルの定義
greeting.protoという名前のファイルを作成し、以下の内容を記入します。
syntax = "proto3";
package greeting;
// サービスの定義
service Greeter {
// SayHelloは一つの挨拶を返します。
rpc SayHello (HelloRequest) returns (HelloReply) {}
}
// HelloRequestはクライアントからのリクエストを定義します。
message HelloRequest {
string name = 1;
}
// HelloReplyはサーバからのレスポンスを定義します。
message HelloReply {
string message = 1;
}
Step 2: サーバー側のコード
次に、greeting_server.pyというPythonファイルを作成し、以下のコードを記入します。このコードは、上で定義したプロトコルに従って、クライアントからの挨拶リクエストに応答します。
from concurrent import futures
import grpc
import greeting_pb2
import greeting_pb2_grpc
class GreeterServicer(greeting_pb2_grpc.GreeterServicer):
def SayHello(self, request, context):
return greeting_pb2.HelloReply(message='Hello, %s!' % request.name)
def serve():
server = grpc.server(futures.ThreadPoolExecutor(max_workers=10))
greeting_pb2_grpc.add_GreeterServicer_to_server(GreeterServicer(), server)
server.add_insecure_port('[::]:50051')
server.start()
server.wait_for_termination()
if __name__ == '__main__':
serve()
Step 3: クライアント側のコード
最後に、greeting_client.pyというPythonファイルを作成し、以下のコードを記入します。このコードは、指定された名前を使ってサーバーに挨拶をリクエストし、サーバーからの応答を表示します。
import grpc
import greeting_pb2
import greeting_pb2_grpc
def run():
channel = grpc.insecure_channel('localhost:50051')
stub = greeting_pb2_grpc.GreeterStub(channel)
response = stub.SayHello(greeting_pb2.HelloRequest(name='world'))
print("Greeter client received: " + response.message)
if __name__ == '__main__':
run()
これでサンプルコードは以上になります。
実行してみましょう。
事前準備
1.関連パッケージのインストール
# pipenvを使った場合
pipenv install grpcio grpcio-tools
- grpcioは、gRPCのPython実装で、クライアントとサーバーの実行に必要です。
- grpcio-toolsには、.protoファイルからPythonのgRPCコードを生成するために必要なプロトコルバッファコンパイラ(protoc)とPythonのプラグインが含まれています。
2.greeting.protoファイルから必要なPythonコードを生成しておく
pipenv run python -m grpc_tools.protoc -I. --python_out=. --grpc_python_out=. greeting.proto
このコマンドは、greeting.protoファイルを使って、greeting_pb2.pyとgreeting_pb2_grpc.pyの2つのPythonファイルを生成します。これらは、定義したプロトコルに基づくサーバーとクライアントのコードに必要です。
- -I.オプションは、.protoファイルが存在するディレクトリを指定します(この場合、カレントディレクトリ)。
- --python_out=.と--grpc_python_out=.オプションは、生成されたPythonファイルを出力するディレクトリを指定します(これもカレントディレクトリ)。
実行する
Step 1: サーバーを起動
pipenv run python greeting_server.py
Step 2: クライアントを実行
pipenv run python greeting_client.py
検証
Greeter client received: Hello, world!
これにより、gRPCを使用してサーバーとクライアント間で通信が正常に行われたことを確認できます。
注意点
- サーバーとクライアントが異なるマシン上で実行される場合は、クライアントのコード内のサーバーのアドレスを適宜変更する必要があります。
- 実際のアプリケーションでは、セキュリティを考慮してTLS/SSLを使用した通信を構成することが推奨されます。
感想
- 非公開の役割の違う複数台のマシンの間同士の通信は、これを使えば便利だな〜と思いました。
- AI時代だからこそ、新しいスキルの勉強がすごく楽になりました。
その他
参考資料: ChatGPT
自分のGithubへアップしておきました。興味があれば、参考にしてください。こちらへ