Upgrade to Pro — share decks privately, control downloads, hide ads and more …

2019-15 gRPC and Protocol Buffers

2019-15 gRPC and Protocol Buffers

Cybozu
PRO

July 31, 2019
Tweet

More Decks by Cybozu

Other Decks in Programming

Transcript

  1. 開運研修2019 スキーマファースト開発入門
    gRPC & Protocol buffers 編
    ymmt

    View Slide

  2. スキーマファースト(schema first)とは
    ▌API の仕様からコードを生成する開発スタイル
    ⚫ API仕様=スキーマ
    ⚫ 仕様と実装の乖離の恐れがない
    ⚫ コードの多くが自動生成できるので開発コストが減る
    ▌対称的に、コードから仕様を生成するスタイルもある
    ⚫ コードファースト(Code First)

    View Slide

  3. Agenda
    ▌Remote Procedure Call (RPC)概説
    ▌Protocol Buffers の基本
    ▌Protocol Buffers 演習
    ▌gRPC の基本
    ▌gRPC の演習

    View Slide

  4. Remote Procedure Call (RPC) とは
    ▌関数コールで、他サーバー上のサービスを呼び出す
    ⚫ 呼び出し関数は stub と称される
    ⚫ 呼び出される関数本体は別の言語で実装可能
    ▌一般に、マシンアーキテクチャや言語に非依存
    ⚫ 呼び出し規約はインタフェース記述言語(IDL)で記述
    ⚫ IDL をコンパイルして stub 類を生成

    View Slide

  5. RPC の特徴
    ▌Good
    ⚫ Stub 関数を使うのは通常とても容易
    ⚫ IDL で書かれた仕様は仕様書としても利用可能
    ▌Bad
    ⚫ 実装の隠蔽度合いが強いためチューニングが困難
    ⚫ (関数呼び出しなので)同期的な処理が基本

    View Slide

  6. IDL コンパイラの仕事
    ▌データ構造のシリアライズ・デシリアライズ
    ⚫ エンディアンに依存しない
    ⚫ 各言語の型に自然にマッピング
    ▌Stub およびサーバー実装の生成
    ⚫ Stub は完全に自動生成可能
    ⚫ サーバー実装は関数本体を除いて自動生成可能
    ▌その他
    ⚫ 仕様書の出力

    View Slide

  7. Protocol Buffers

    View Slide

  8. Protocol Buffers とは
    ▌Google が開発した IDL
    ⚫ https://developers.google.com/protocol-buffers/
    ⚫ Version 2 と3 があるが、これから使うなら 3 で
    ▌言語サポートが豊富
    ⚫ 公式:C++, C#, Dart, Java, JavaScript,
    Objective-C, PHP, Python, Ruby
    ⚫ サードパーティー実装も多数存在
    https://github.com/protocolbuffers/protobuf/blob/master/docs/third_party.md

    View Slide

  9. 特徴
    • protoc コマンド(IDLコンパイラ)を簡単に機能拡張できる
    • gRPC もプラグインで実装
    拡張性が高い
    • 結果として IDL ファイルの可読性が高い
    仕様が簡潔
    • すべてのフィールドは Optional
    • IDL にない昔のフィールドは無視
    後方互換性への配慮

    View Slide

  10. IDL 言語
    ▌.proto 拡張子のファイルに書く
    ▌message を定義していく
    ⚫ 構造体(struct, object)相当
    ⚫ フィールドには数値や文字列といったスカラや他の
    message, それらの配列(repeated), mapを指定できる
    ⚫ 各フィールドにはユニークな数値 ID がある
    ⚫ フィールドがない場合の既定値が定められている

    View Slide

  11. Import と Well-Known-Types
    ▌他所で定義された Message を再利用できる
    ⚫ Import する .proto ファイルはローカルにおく必要あり
    ⚫ ファイルの場所は protoc –IDIR で指定
    ▌Well-Known-Types
    ⚫ Timestamp などよく利用される定義済み Message
    ⚫ protoc 同梱の .proto ファイルを Import して使う
    ⚫ 各言語の型に変換するライブラリもある
    ⚫例:github.com/golang/protobuf/ptypes

    View Slide

  12. proto ファイルの例
    syntax = “proto3”; // Protocol Buffers v3 であることを宣言
    package tutorial; // import する際に使われるパッケージ名
    import “google/protobuf/timestamp.proto”; // Well-Known-Types (WKT)
    option java_package = “com.example.tutorial”; // option は protoc が生成するコードへの指示
    option java_outer_classname = “AddressBookProtos”; // message のシリアライズ形式には一切影響しない
    message Person {
    string name = 1; // フィールドには数値識別子が必要(1~2^29-1)
    int32 id = 2; // 19000~19999 の識別子は予約されているので使わない
    string email = 3;
    enum PhoneType {
    MOBILE = 0; // enum は必ず =0 の要素から始めなければいけない
    HOME = 1; // 0 は、フィールドがないときのデフォルト値となる
    WORK = 2;
    }
    message PhoneNumber { // message の内側に message や enum を定義することができる
    string number = 1;
    PhoneType type = 2;
    }
    repeated PhoneNumber phones = 4; // repeated のフィールドは 0 個以上の要素を持てる(リスト)
    google.protobuf.Timestamp last_updated = 5; // import した message はパッケージ名で修飾して参照する
    }

    View Slide

  13. 演習の準備
    ▌protoc (と gRPC)が使えるようにしてください
    ⚫ https://grpc.io/docs/quickstart/
    ▌Go, Java, Node 辺りが良いと思います
    ⚫ 一部の言語はサーバー側の実装に不向きです
    ⚫ 講師は Go でやります
    ⚫ https://github.com/ymmt2005/demo-protobuf

    View Slide

  14. 演習:シリアライズ・デシリアライズ
    ▌以下の proto ファイルを使ってデータをシリアライ
    ズ・デシリアライズしてみましょう
    ⚫ https://github.com/protocolbuffers/protobuf/blob/master/examples/addressbook.proto
    ⚫ Protocol Buffers のチュートリアルにヒントがあります
    ▌シリアライズしたデータをファイルに保存しましょう
    ⚫ 次の演習のため

    View Slide

  15. 演習:proto ファイルの更新
    ▌前の proto ファイルにフィールドを足してください
    ▌足した proto ファイルをコンパイルし、前の演習で保
    存したデータをデシリアライズしてみよう
    ▌余裕があれば、他の言語でデシリアライズしてみよう

    View Slide

  16. 演習:protoc-gen-doc で仕様書生成
    ▌protoc-gen-doc
    ⚫ https://github.com/pseudomuto/protoc-gen-doc
    ⚫ protoc のプラグイン
    ⚫ HTML や Markdown の仕様書を生成
    ⚫ proto ファイルにコメントを足して良い感じにしましょう

    View Slide

  17. Further readings
    ▌Language Specification
    ⚫ Protocol Buffers v3 の IDL 言語仕様書
    ▌Style Guide
    ⚫ proto ファイルの良い書き方
    ▌Backward and Forward Compatibility, Protobuf Versioning,
    Serialization
    ⚫ 互換性を維持する方法論

    View Slide

  18. gRPC

    View Slide

  19. gRPC とは
    ▌Google が開発した RPC 実装
    ▌Protocol Buffers を IDL として採用
    ▌Half & Full duplex なストリーム処理をサポート
    ⚫ イベントの監視などに便利
    ▌HTTP/2 frame を利用
    ⚫ TCP/IP 必須ではなく UNIX ドメインソケットでもOK

    View Slide

  20. gRPC とマイクロサービス
    ▌以下の理由で gRPC が良く採用されている
    ⚫ Protocol Buffers で後方互換性を確保しやすい
    ⚫ IDL ファイルによる仕様の明確化
    ⚫ 実装言語の選択肢が多い
    ⚫ クライアントが自動生成できる
    ⚫ ストリーム処理が可能

    View Slide

  21. service 定義
    ▌Protocol Buffers は service も定義できる
    ⚫ service を gRPC プラグインが解釈してコード生成する
    ⚫ プラグインがないと単に無視される
    ▌service は複数の rpc を定義できる
    ⚫ /service/rpc が HTTP/2 の :path 疑似ヘッダーになる
    ⚫ HTTP/2 を扱えるリバースプロキシを利用可能
    ▌各 rpc には stream 指定ができる

    View Slide

  22. service の例
    message Empty {} // 引数・戻り値が不要な RPC 用の空メッセージ
    message GetLVResponse {
    string name = 1;

    }
    service VGService {
    rpc GetLVList(Empty) returns (GetLVListResponse); // 引数と戻り値の型はそれぞれひとつの指定が必須
    rpc Watch(Empty) returns (stream WatchResponse); // サーバーが WatchResponse をストリームする RPC
    rpc Notify(stream VGEvent) returns (Empty); // クライアントが VGEvent をストリームする RPC
    }

    View Slide

  23. gRPC ライブラリ
    ▌gRPC の通信処理はランタイムライブラリで提供
    ⚫ Go: https://github.com/grpc/grpc-go
    ⚫ Java: https://github.com/grpc/grpc-java
    ⚫ Python: https://grpc.github.io/grpc/python/
    ▌gRPC では標準的なエラーコードが定義されている
    ⚫ 各言語での利用例が以下にある
    https://github.com/avinassh/grpc-errors

    View Slide

  24. 演習:gRPC クライアント
    ▌以下のリポジトリにある greeter_server に接続する
    クライアントを開発してみよう
    ⚫ https://github.com/grpc/grpc-go/tree/master/examples
    ▌proto ファイルからクライアント用 stub を生成
    ⚫ https://github.com/grpc/grpc-go/blob/master/examples/helloworld/helloworld/helloworld.proto

    View Slide

  25. 演習:gRPC ストリーミング
    ▌二人一組で、以下のサービスを proto から設計
    ⚫ 要求された間隔毎に、指定された形式で時報を返す
    ▌片方がサーバーを、片方がクライアントを実装
    ▌実装例
    ⚫ https://github.com/ymmt2005/demo-grpc

    View Slide

  26. Further readings
    ▌Guides
    ⚫ 認証やエラー処理といった大事なことが書いてあります
    ▌go-grpc-middleware
    ⚫ 分散トレーシングやリクエストログ、rate limit など
    ▌lvmd
    ⚫ LVM を操作する gRPC マイクロサービス
    ⚫ 実例としてどうぞ

    View Slide

  27. gRPC-Web
    ▌https://github.com/grpc/grpc-web
    ▌Web ブラウザで gRPC プロトコルは使えない
    ⚫ gRPC は HTTP/2 必須だがブラウザはそうではないため
    ▌JavaScript で扱えるプロトコル(gRPC-Web)を規定
    ⚫ プロキシで gRPC-Web を gRPC に変換
    ▌Client-side ストリーミング等わずかな制限あり

    View Slide

  28. GraphQL 編に続く

    View Slide