Upgrade to Pro
— share decks privately, control downloads, hide ads and more …
Speaker Deck
Features
Speaker Deck
PRO
Sign in
Sign up for free
Search
Search
2019-15 gRPC and Protocol Buffers
Search
Cybozu
PRO
July 31, 2019
Programming
4
160k
2019-15 gRPC and Protocol Buffers
Cybozu
PRO
July 31, 2019
Tweet
Share
More Decks by Cybozu
See All by Cybozu
サイボウズフロントエンドエキスパートチームについて / FrontendExpert Team
cybozuinsideout
PRO
5
38k
2024/11/25 ReDesigner Online Meetup 会社紹介
cybozuinsideout
PRO
0
290
サイボウズ 開発本部採用ピッチ / Cybozu Engineer Recruit
cybozuinsideout
PRO
9
46k
テクニカルライティング
cybozuinsideout
PRO
4
410
サイボウズのアジャイルクオリティ2024
cybozuinsideout
PRO
3
340
モブに早く慣れたい人のためのガイド2024
cybozuinsideout
PRO
3
470
モバイル
cybozuinsideout
PRO
3
240
ソフトウェアライセンス
cybozuinsideout
PRO
4
220
ソフトウェアテスト
cybozuinsideout
PRO
3
340
Other Decks in Programming
See All in Programming
採用事例の少ないSvelteを選んだ理由と それを正解にするためにやっていること
oekazuma
2
1.1k
アクターシステムに頼らずEvent Sourcingする方法について
j5ik2o
4
360
Асинхронность неизбежна: как мы проектировали сервис уведомлений
lamodatech
0
990
iOS開発におけるCopilot For XcodeとCode Completion / copilot for xcode
fuyan777
1
110
Kaigi on Railsに初参加したら、その日にLT登壇が決定した件について
tama50505
0
110
テストコードのガイドライン 〜作成から運用まで〜
riku929hr
5
960
103 Early Hints
sugi_0000
1
260
create_tableをしただけなのに〜囚われのuuid編〜
daisukeshinoku
0
290
range over funcの使い道と非同期N+1リゾルバーの夢 / about a range over func
mackee
0
110
これでLambdaが不要に?!Step FunctionsのJSONata対応について
iwatatomoya
2
3.8k
AppRouterを用いた大規模サービス開発におけるディレクトリ構成の変遷と問題点
eiganken
1
160
Stackless и stackful? Корутины и асинхронность в Go
lamodatech
0
970
Featured
See All Featured
Building an army of robots
kneath
302
44k
The Art of Delivering Value - GDevCon NA Keynote
reverentgeek
8
1.2k
Why You Should Never Use an ORM
jnunemaker
PRO
54
9.1k
Reflections from 52 weeks, 52 projects
jeffersonlam
347
20k
How STYLIGHT went responsive
nonsquared
96
5.2k
The Psychology of Web Performance [Beyond Tellerrand 2023]
tammyeverts
45
2.2k
The Language of Interfaces
destraynor
154
24k
Build your cross-platform service in a week with App Engine
jlugia
229
18k
Fashionably flexible responsive web design (full day workshop)
malarkey
405
66k
CSS Pre-Processors: Stylus, Less & Sass
bermonpainter
356
29k
Statistics for Hackers
jakevdp
796
220k
How to Ace a Technical Interview
jacobian
276
23k
Transcript
開運研修2019 スキーマファースト開発入門 gRPC & Protocol buffers 編 ymmt
スキーマファースト(schema first)とは ▌API の仕様からコードを生成する開発スタイル ⚫ API仕様=スキーマ ⚫ 仕様と実装の乖離の恐れがない ⚫ コードの多くが自動生成できるので開発コストが減る
▌対称的に、コードから仕様を生成するスタイルもある ⚫ コードファースト(Code First)
Agenda ▌Remote Procedure Call (RPC)概説 ▌Protocol Buffers の基本 ▌Protocol Buffers
演習 ▌gRPC の基本 ▌gRPC の演習
Remote Procedure Call (RPC) とは ▌関数コールで、他サーバー上のサービスを呼び出す ⚫ 呼び出し関数は stub と称される
⚫ 呼び出される関数本体は別の言語で実装可能 ▌一般に、マシンアーキテクチャや言語に非依存 ⚫ 呼び出し規約はインタフェース記述言語(IDL)で記述 ⚫ IDL をコンパイルして stub 類を生成
RPC の特徴 ▌Good ⚫ Stub 関数を使うのは通常とても容易 ⚫ IDL で書かれた仕様は仕様書としても利用可能 ▌Bad
⚫ 実装の隠蔽度合いが強いためチューニングが困難 ⚫ (関数呼び出しなので)同期的な処理が基本
IDL コンパイラの仕事 ▌データ構造のシリアライズ・デシリアライズ ⚫ エンディアンに依存しない ⚫ 各言語の型に自然にマッピング ▌Stub およびサーバー実装の生成 ⚫
Stub は完全に自動生成可能 ⚫ サーバー実装は関数本体を除いて自動生成可能 ▌その他 ⚫ 仕様書の出力
Protocol Buffers
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
特徴 • protoc コマンド(IDLコンパイラ)を簡単に機能拡張できる • gRPC もプラグインで実装 拡張性が高い • 結果として
IDL ファイルの可読性が高い 仕様が簡潔 • すべてのフィールドは Optional • IDL にない昔のフィールドは無視 後方互換性への配慮
IDL 言語 ▌.proto 拡張子のファイルに書く ▌message を定義していく ⚫ 構造体(struct, object)相当 ⚫
フィールドには数値や文字列といったスカラや他の message, それらの配列(repeated), mapを指定できる ⚫ 各フィールドにはユニークな数値 ID がある ⚫ フィールドがない場合の既定値が定められている
Import と Well-Known-Types ▌他所で定義された Message を再利用できる ⚫ Import する .proto
ファイルはローカルにおく必要あり ⚫ ファイルの場所は protoc –IDIR で指定 ▌Well-Known-Types ⚫ Timestamp などよく利用される定義済み Message ⚫ protoc 同梱の .proto ファイルを Import して使う ⚫ 各言語の型に変換するライブラリもある ⚫例:github.com/golang/protobuf/ptypes
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 はパッケージ名で修飾して参照する }
演習の準備 ▌protoc (と gRPC)が使えるようにしてください ⚫ https://grpc.io/docs/quickstart/ ▌Go, Java, Node 辺りが良いと思います
⚫ 一部の言語はサーバー側の実装に不向きです ⚫ 講師は Go でやります ⚫ https://github.com/ymmt2005/demo-protobuf
演習:シリアライズ・デシリアライズ ▌以下の proto ファイルを使ってデータをシリアライ ズ・デシリアライズしてみましょう ⚫ https://github.com/protocolbuffers/protobuf/blob/master/examples/addressbook.proto ⚫ Protocol Buffers
のチュートリアルにヒントがあります ▌シリアライズしたデータをファイルに保存しましょう ⚫ 次の演習のため
演習:proto ファイルの更新 ▌前の proto ファイルにフィールドを足してください ▌足した proto ファイルをコンパイルし、前の演習で保 存したデータをデシリアライズしてみよう ▌余裕があれば、他の言語でデシリアライズしてみよう
演習:protoc-gen-doc で仕様書生成 ▌protoc-gen-doc ⚫ https://github.com/pseudomuto/protoc-gen-doc ⚫ protoc のプラグイン ⚫ HTML
や Markdown の仕様書を生成 ⚫ proto ファイルにコメントを足して良い感じにしましょう
Further readings ▌Language Specification ⚫ Protocol Buffers v3 の IDL
言語仕様書 ▌Style Guide ⚫ proto ファイルの良い書き方 ▌Backward and Forward Compatibility, Protobuf Versioning, Serialization ⚫ 互換性を維持する方法論
gRPC
gRPC とは ▌Google が開発した RPC 実装 ▌Protocol Buffers を IDL
として採用 ▌Half & Full duplex なストリーム処理をサポート ⚫ イベントの監視などに便利 ▌HTTP/2 frame を利用 ⚫ TCP/IP 必須ではなく UNIX ドメインソケットでもOK
gRPC とマイクロサービス ▌以下の理由で gRPC が良く採用されている ⚫ Protocol Buffers で後方互換性を確保しやすい ⚫
IDL ファイルによる仕様の明確化 ⚫ 実装言語の選択肢が多い ⚫ クライアントが自動生成できる ⚫ ストリーム処理が可能
service 定義 ▌Protocol Buffers は service も定義できる ⚫ service を
gRPC プラグインが解釈してコード生成する ⚫ プラグインがないと単に無視される ▌service は複数の rpc を定義できる ⚫ /service/rpc が HTTP/2 の :path 疑似ヘッダーになる ⚫ HTTP/2 を扱えるリバースプロキシを利用可能 ▌各 rpc には stream 指定ができる
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 }
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
演習: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
演習:gRPC ストリーミング ▌二人一組で、以下のサービスを proto から設計 ⚫ 要求された間隔毎に、指定された形式で時報を返す ▌片方がサーバーを、片方がクライアントを実装 ▌実装例 ⚫
https://github.com/ymmt2005/demo-grpc
Further readings ▌Guides ⚫ 認証やエラー処理といった大事なことが書いてあります ▌go-grpc-middleware ⚫ 分散トレーシングやリクエストログ、rate limit など
▌lvmd ⚫ LVM を操作する gRPC マイクロサービス ⚫ 実例としてどうぞ
gRPC-Web ▌https://github.com/grpc/grpc-web ▌Web ブラウザで gRPC プロトコルは使えない ⚫ gRPC は HTTP/2
必須だがブラウザはそうではないため ▌JavaScript で扱えるプロトコル(gRPC-Web)を規定 ⚫ プロキシで gRPC-Web を gRPC に変換 ▌Client-side ストリーミング等わずかな制限あり
GraphQL 編に続く