gRPC について
gRPC はリモートからデータ取得、データ変更するRPCの一種
google が作って、http/2 とうまく協調するようにしている
一言でいえば、C構造体をそのままぶん投げるプロトコル。
サーバーとクライアントが事前にお互いに構造を知っていれば、JSONみたいに配列にしたり、オブジェクトキーを入れなくていいよね。
乱暴に言えば、sqlite3 で1行転送してるようなもん。お互いテーブル構造を知ってれば問題ないでしょ?みたいな感じ。
準備する
├── proto │ └── user.proto ├── protos │ └── user.proto ├── py │ ├── Pipfile │ ├── Pipfile.lock │ ├── client.py │ ├── server.py │ ├── user_pb2.py │ └── user_pb2_grpc.py └── users.json
python を準備する
PIPENV_VENV_IN_PROJECT=1 pipenv install pipenv run pip install pipenv run pip3 install grpcio grpcio-tools
protoを作る
protoを作る。データベースでいうスキーマ。C言語でいう構造体。
proto が特徴的なのは、次の3点だと感じた。
JAVAのクラス定義だとメンバとメソッド雛形が分けづらい
Cの構造体だと名前空間が使えない。
データベースのスキーマだと参照定義ができない
JSONだと冗長になりすぎる
という部分が解消されて使いやすい「データ型の定義」だと感じた。
SQLiteをリモート転送するには便利そうですよね。
server.py
自動生成されたクラスを継承して作る
client.py
自動生成されたクラスを呼び出して使う。
リクエスト実験
サーバー起動
pipenv run python server.py
クライアント側
pipenv run python client.py 1 pipenv run python client.py 2 pipenv run python client.py 3 pipenv run python client.py 10
grpcurl でリクエストを送る
grpcurl -plaintext -import-path ../protos -proto user.proto -d ' { "id": 1 } ' localhost:1234 UserManager.get { "user": { "id": 1, "nickname": "admin", "mailAddress": "admin@example.com", "userType": "ADMINISTRATOR" } }
http2
http2 らしいのでtcpdump でパケットを見てみる。
cURLで叩きたい
HTTP/2 なので、cURLで叩けそうですが。絶対めんどくさい。
バイナリ転送が基本。まるでC構造体のようなProtoのまま転送しているので、中身を見ても仕方ないし、手動でリクエストを送るのも手間である。
どうしてもやりたきゃ、プロキシする必要がありそうです。
っていうか、冗長性を排してバイナリ転送するのがgRPCだし
参考資料
サービス間通信のための新技術「gRPC」入門 | さくらのナレッジ
https://engineering.mercari.com/blog/entry/2019-05-24-120000/