Web

実践入門「gRPC」とは?

投稿日:2023年11月1日 更新日:

HTTPを使ったAPI定義には、REST APIとGraphQLがあります。これらのAPI定義は、外部に公開するための「外向け」のものです。それに対し、「内向け」のプロセス間通信(IPC)のAPI定義として、Googleによって発案されたgRPCがあります。

gRPCは、REST APIとGraphQLよりも高速であり、異なるプラットフォームと互換性があるため、プロセス間通信に向いています。

■ gRPCの概要

gRPCとは、名前の通り、リモートプロシージャコール(RPC)です。
RPCは昔からある技術であり、特徴として以下が挙げられます。

1)Linux、Windows、iOS、AndroidなどのOS、C/C++、C#、Java、JavaScript、PHP、Python、Objective-C、Kotlinなどのプログラミング言語に依存しないこと
2)インタフェース定義のスクリプトを使って、各OS/言語用のスタブコードを自動生成すること

これによって、異なる環境であっても、ローカル関数の呼び出しと同様にプロセス間通信を実現できます。

gRPCも上記と同様の特徴を持ち、次のような仕組みで実現されます。

通信プロトコルに「HTTP/2」、インタフェース定義にGoogle発案の「ProtocolBuffers」を使います。
HTTP/2はストリームと呼ばれる通信の同時並列化、ProtocolBuffersはシリアライズと呼ばれる通信するデータ量の削減によって転送速度の向上が図られています。

インタフェース定義からツールを使って、クライアントとサーバ間で通信をするためのスタブコードを生成します。クライアントアプリは、スタブコードをリンクし、インタフェースを呼び出します。
サーバアプリは、スタブコードをリンクし、インタフェースの機能を実装することでサービスを提供します。

■ ProtocolBuffersでのインタフェース定義

データ型には、文字列(string)、整数(int32/64、uint32/64)、浮動小数点(float/double)、ブーリアン(bool)、バイト(byte)などがあります。これらを組み合わせ、構造体(message型)を定義することもできます。

インタフェースは、これらのデータ型を処理する関数として定義します。
例えば、以下のような定義となります。

// ProtocolBuffersバージョン3の規定を使用する
syntax = "proto3";

// MyMessage型を定義
message MyMessage {
  string name = 1;
  uint32 age = 2;
  string message = 3;
}

// Helloリクエスト型
message HelloRequest {
  uint32 no = 1;
}

// Helloレスポンス型
message HelloResponse {
  bool result = 1;
  MyMessage mymessage = 2;
}

// Helloインタフェース
service Hello {
  // myfunc関数
  rpc myfunc (HelloRequest) returns (HelloResponse) {}
}

このインタフェース定義からスタブコードを生成します。

Python環境では、gRPCを使うため次のパッケージをインストールします。

pip install grpcio grpcio-tools


その後、インタフェース定義(hello.proto)からスタブコードを生成します。
(カレントディレクトリにあるhello.protoファイルから、カレントディレクトリにスタブコードを生成します)

python -m grpc_tools.protoc -I. –python_out=. –grpc_python_out=. hello.proto


その結果、以下のように、スタブコードが生成されます。

hello_pb2.py        ※データをシリアライズするためのコード
hello_pb2_grpc.py     ※インタフェースのコード 

■ PythonによるgRPCの実装サンプル

実装サンプルを以下に示します。

・クライアントのサンプルソース

# -*- coding: utf-8 -*-
import pprint

# スタブのインポート
import grpc
import hello_pb2
import hello_pb2_grpc

# リクエストを作成する
req = hello_pb2.HelloRequest(no=1)

# サーバーに接続する
connection=grpc.insecure_channel("127.0.0.1:50000") 

# 送信先の「stub」を作成する
stub = hello_pb2_grpc.HelloStub(connection)

# リクエストを送信する
response = stub.myfunc(req)

# 取得したレスポンスの表示
pprint.pprint(response)

・サーバのサンプルソース

# -*- coding: utf-8 -*-

# gRPCのサーバー実装ではThreadPoolを利用
from concurrent.futures import ThreadPoolExecutor

# スタブのインポート
import grpc
import hello_pb2
import hello_pb2_grpc

# サービス定義から生成されたクラスを継承して、定義したリモートプロシージャに対応するメソッドを実装する
class Hello(hello_pb2_grpc.HelloServicer):
    def myfunc(self, request, context):

        # requestからクライアントから送信された値を取得する
        no = request.no
        print('request no = '+str(no))

        # MyMessageインスタンスを作成する
        mymessage = hello_pb2.MyMessage()
        mymessage.name = "watanabe"
        mymessage.age = 99
        mymessage.message = "hello world"

        # HelloResponseインスタンスを返す
        return hello_pb2.HelloResponse(result=True,mymessage=mymessage)

if __name__ == '__main__':
    
    # Serverインスタンス作成
    server = grpc.server(ThreadPoolExecutor(max_workers=2))

    # Helloインスタンス、Serverインスタンスを登録
    hello_pb2_grpc.add_HelloServicer_to_server(Hello(), server)

    # 50000番ポートで待ち受け
    server.add_insecure_port('[::]:50000')

    # 開始
    server.start()

    # 後処理
    server.wait_for_termination()

実行結果は以下となります。

・クライアント

・サーバ

■ まとめ

プロセス間通信には、パイプ、キュー、ソケット、メッセージなど様々な方式があり、同期・非同期通信が実現されてきました。これらは密結合であり、限定されたソフトウェアやプログラム間でのみでの通信を行うためのものでした。

gRPCでは、より疎結合かつ汎用性のある方式を採用することで、プロセス間通信をオープンに実施できるようになります。これにより、モノシリックアーキテクチャからマイクロサービスアーキテクチャへの移行を促す技術となります。


ソフトウェア開発・システム開発業務/セキュリティ関連業務/ネットワーク関連業務/最新技術に関する業務など、「学習力×発想力×達成力×熱意」で技術開発の実現をサポート。お気軽にお問合せ下さい

-Web

執筆者:


comment

メールアドレスが公開されることはありません。

関連記事

リモート会議API「Zoom REST API」の実践入門(Server -To-Server OAuth)

リモート会議を開催するとき、アプリケーションのZoomを使われてる人も多いと思います。Zoomには、Pythonによってプログラミング可能なWeb-APIであるREST APIが用意されています。この …

はじめてのノーコードWebアプリ開発ツール「Bubble」入門

ノーコードによるアプリ開発ツールに、「Bubble」があります。Bubbleは、Webアプリの開発に特化しており、開発ツールのGUIを駆使することで、文字通り、プログラミングすることなく、Webアプリ …

GCPでのWebサービスの作り方(Python、Flask、MYSQL、Mail、Apache) 2/2

以下からの続きとなります。GCPでのWebサービスの作り方(Python、Flask、MYSQL、Mail、Apache) 1/2 ■  ステップ4)GCPにWebアプリケーション環境をセットアップ …

PythonによるWeb開発「Flask」入門

WebアプリケーションをPythonを使って手軽に開発できるマイクロフレームワークがFlaskです。Webアプリケーション開発と言えばPHPがありますが、Flaskの最大の特徴は、プログラミング言語の …

実践入門「GraphQL」とは?

サービスを定義する手段として、REST APIの他、GraphQLがあります。これは、データベースのデータを操作するためのSQLのように、サーバ内にあるデータを直接的にアクセスするようなインタフェース …

Chinese (Simplified)Chinese (Traditional)EnglishFilipinoFrenchGermanHindiJapaneseKoreanMalayThaiVietnamese