Upgrade to PRO for Only $50/Year—Limited-Time Offer! 🔥
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
2024/11/25 ReDesigner Online Meetup 会社紹介
cybozuinsideout
PRO
0
230
サイボウズ 開発本部採用ピッチ / Cybozu Engineer Recruit
cybozuinsideout
PRO
9
46k
テクニカルライティング
cybozuinsideout
PRO
4
360
サイボウズのアジャイルクオリティ2024
cybozuinsideout
PRO
3
310
モブに早く慣れたい人のためのガイド2024
cybozuinsideout
PRO
3
430
モバイル
cybozuinsideout
PRO
3
220
ソフトウェアライセンス
cybozuinsideout
PRO
4
200
ソフトウェアテスト
cybozuinsideout
PRO
3
310
自動テスト
cybozuinsideout
PRO
3
310
Other Decks in Programming
See All in Programming
Keeping it Ruby: Why Your Product Needs a Ruby SDK - RubyWorld 2024
envek
0
120
SymfonyCon Vienna 2025: Twig, still relevant in 2025?
fabpot
3
960
Webエンジニア主体のモバイルチームの 生産性を高く保つためにやったこと
igreenwood
0
100
.NET 9アプリをCGIとして レンタルサーバーで動かす
mayuki
1
760
Haze - Real time background blurring
chrisbanes
1
450
型のインスタンス化は非常に深く、無限である可能性があります。
kimitashoichi
0
150
React + Tauriでデスクトップアプリ開発に入門してみた
ynishimura0922
0
220
TypeScript でバックもやるって実際どう? 実運用で困ったこと3選
yuichiro_serita
17
7.6k
PaaSとSaaSの境目で信頼性と開発速度を両立する 〜TROCCO®︎のこれまでとこれから〜
gtnao
6
7.2k
アニメーションを最深まで理解してパフォーマンスを向上させる
mine2424
0
110
プロダクトの品質に コミットする / Commit to Product Quality
pekepek
1
700
Jakarta EE meets AI
ivargrimstad
0
950
Featured
See All Featured
Six Lessons from altMBA
skipperchong
27
3.5k
Agile that works and the tools we love
rasmusluckow
328
21k
Building Better People: How to give real-time feedback that sticks.
wjessup
365
19k
We Have a Design System, Now What?
morganepeng
51
7.3k
Writing Fast Ruby
sferik
627
61k
Principles of Awesome APIs and How to Build Them.
keavy
126
17k
Building a Scalable Design System with Sketch
lauravandoore
459
33k
Visualizing Your Data: Incorporating Mongo into Loggly Infrastructure
mongodb
44
9.3k
How STYLIGHT went responsive
nonsquared
95
5.2k
Optimizing for Happiness
mojombo
376
70k
Making Projects Easy
brettharned
116
5.9k
Evolution of real-time – Irina Nazarova, EuRuKo, 2024
irinanazarova
4
410
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 編に続く