SlideShare una empresa de Scribd logo
1 de 56
Descargar para leer sin conexión
GKEとgRPCで実装する
多言語対応・スケーラブルな内部API
高橋 秀平
2018/5/26 JJUG CCC Spring
Analytics Innovation Company
©BrainPad Inc.
Strictly Confidential
1
自己紹介
名前: 高橋秀平
所属: 株式会社ブレインパッド
仕事: インターネット広告関連ツール開発
Java歴: 5年くらい
Analytics Innovation Company
©BrainPad Inc.
Strictly Confidential
2
話すこと
インターネット広告API呼び出しサービスを
Java + GKE + gRPCで開発している経験を元に、
実際のシステム開発に関するTipsをご紹介します
Analytics Innovation Company
©BrainPad Inc.
Strictly Confidential
3
アジェンダ
• gRPCとは
• GKEとは
• 実装上のTips
• ヘルスチェック
• エラーの受け渡し
• シャットダウン
• Java ⇔ protobuf 変換
Analytics Innovation Company
©BrainPad Inc.
Strictly Confidential
4
gRPCとは
Analytics Innovation Company
©BrainPad Inc.
Strictly Confidential
5
gRPCとは
• Googleによって開発され、2015年にオープンソース化されたRPCフレームワーク
• HTTP/2 による通信
• Protocol Buffer を IDL として採用
• クライアント・サーバともに Java, go, Python 等複数言語に対応
• 高速かつ高機能
• Cloud Native Computing Foundationの6番目のプロジェクト
• Google Ads API (beta) では JSON REST形式の他にgRPC形式をサポート
Analytics Innovation Company
©BrainPad Inc.
Strictly Confidential
6
gRPCとは
• 利用の流れ
• .protoファイルにサービスやデータの定義を記述する
• .protoファイルから各言語のソースコードを生成する
• サーバサイド・クライアントサイドを実装する
Analytics Innovation Company
©BrainPad Inc.
Strictly Confidential
7
サービスやデータの定義
// サービスの定義
service Greeter {
// Sends a greeting
rpc SayHello (HelloRequest) returns (HelloReply) {}
}
// リクエスト・レスポンスの型の定義
message HelloRequest {
string name = 1;
}
message HelloReply {
string message = 1;
}
Analytics Innovation Company
©BrainPad Inc.
Strictly Confidential
8
サービスやデータの定義
// サービスの定義
service Greeter {
// Sends a greeting
rpc SayHello (HelloRequest) returns (HelloReply) {}
}
// リクエスト・レスポンスの型の定義
message HelloRequest {
string name = 1;
}
message HelloReply {
string message = 1;
}
Analytics Innovation Company
©BrainPad Inc.
Strictly Confidential
9
サービスやデータの定義
// サービスの定義
service Greeter {
// Sends a greeting
rpc SayHello (HelloRequest) returns (HelloReply) {}
}
// リクエスト・レスポンスの型の定義
message HelloRequest {
string name = 1;
}
message HelloReply {
string message = 1;
}
Analytics Innovation Company
©BrainPad Inc.
Strictly Confidential
10
.protoファイルから各言語のソースコードを生成する
• protoc コマンドを利用
protoc --proto_path=src --java_out=build/gen src/greeter.proto
• Mavenを利用している場合は os72 / protoc-jar-maven-plugin なども利用可能
Analytics Innovation Company
©BrainPad Inc.
Strictly Confidential
11
サーバサイドの実装
@GRpcService
public class GreeterImpl extends GreeterGrpc.GreeterImplBase {
@Override
public void sayHello(HelloRequest req,
StreamObserver<HelloReply> responseObserver) {
HelloReply reply = HelloReply.newBuilder()
.setMessage("Hello " + req.getName())
.build();
responseObserver.onNext(reply);
responseObserver.onCompleted();
} // ※ 参考
service Greeter {
rpc SayHello (HelloRequest) returns (HelloReply) {}
}
Analytics Innovation Company
©BrainPad Inc.
Strictly Confidential
12
サーバサイドの実装
@GRpcService
public class GreeterImpl extends GreeterGrpc.GreeterImplBase {
@Override
public void sayHello(HelloRequest req,
StreamObserver<HelloReply> responseObserver) {
HelloReply reply = HelloReply.newBuilder()
.setMessage("Hello " + req.getName())
.build();
responseObserver.onNext(reply);
responseObserver.onCompleted();
} // ※ 参考
service Greeter {
rpc SayHello (HelloRequest) returns (HelloReply) {}
}
.protoで定義したServiceに対応した
クラスが生成される
Analytics Innovation Company
©BrainPad Inc.
Strictly Confidential
13
サーバサイドの実装
@GRpcService
public class GreeterImpl extends GreeterGrpc.GreeterImplBase {
@Override
public void sayHello(HelloRequest req,
StreamObserver<HelloReply> responseObserver) {
HelloReply reply = HelloReply.newBuilder()
.setMessage("Hello " + req.getName())
.build();
responseObserver.onNext(reply);
responseObserver.onCompleted();
} // ※ 参考
service Greeter {
rpc SayHello (HelloRequest) returns (HelloReply) {}
}
対応するメソッドをオーバーライド
Analytics Innovation Company
©BrainPad Inc.
Strictly Confidential
14
サーバサイドの実装
@GRpcService
public class GreeterImpl extends GreeterGrpc.GreeterImplBase {
@Override
public void sayHello(HelloRequest req,
StreamObserver<HelloReply> responseObserver) {
HelloReply reply = HelloReply.newBuilder()
.setMessage("Hello " + req.getName())
.build();
responseObserver.onNext(reply);
responseObserver.onCompleted();
} // ※ 参考
service Greeter {
rpc SayHello (HelloRequest) returns (HelloReply) {}
}
.protoで指定した引数は第一引数
戻り値はメソッドの戻り値ではなく第二引数
Analytics Innovation Company
©BrainPad Inc.
Strictly Confidential
15
サーバサイドの実装
@GRpcService
public class GreeterImpl extends GreeterGrpc.GreeterImplBase {
@Override
public void sayHello(HelloRequest req,
StreamObserver<HelloReply> responseObserver) {
HelloReply reply = HelloReply.newBuilder()
.setMessage("Hello " + req.getName())
.build();
responseObserver.onNext(reply);
responseObserver.onCompleted();
} // ※ 参考
service Greeter {
rpc SayHello (HelloRequest) returns (HelloReply) {}
}
クライアントからのリクエストは
reqからアクセス可能
Analytics Innovation Company
©BrainPad Inc.
Strictly Confidential
16
サーバサイドの実装
@GRpcService
public class GreeterImpl extends GreeterGrpc.GreeterImplBase {
@Override
public void sayHello(HelloRequest req,
StreamObserver<HelloReply> responseObserver) {
HelloReply reply = HelloReply.newBuilder()
.setMessage("Hello " + req.getName())
.build();
responseObserver.onNext(reply);
responseObserver.onCompleted();
} // ※ 参考
service Greeter {
rpc SayHello (HelloRequest) returns (HelloReply) {}
}
戻り値はStreamObserverのonNextへ
Analytics Innovation Company
©BrainPad Inc.
Strictly Confidential
17
クライアントサイドの実装
private ManagedChannel channel = ManagedChannelBuilder
.forAddress(HOST, PORT)
.usePlaintext(true).build();
private GreeterGrpc.GreeterBlockingStub stub =
GreeterGrpc.newBlockingStub(channel);
public void greet(String name) {
HelloRequest request = HelloRequest.newBuilder()
.setName(name)
.build();
HelloReply response = stub.sayHello(request);
logger.info("Greeting: " + response.getMessage());
}
// ※ 参考
service Greeter {
rpc SayHello (HelloRequest) returns (HelloReply) {}
}
Analytics Innovation Company
©BrainPad Inc.
Strictly Confidential
18
クライアントサイドの実装
private ManagedChannel channel = ManagedChannelBuilder
.forAddress(HOST, PORT)
.usePlaintext(true).build();
private GreeterGrpc.GreeterBlockingStub stub =
GreeterGrpc.newBlockingStub(channel);
public void greet(String name) {
HelloRequest request = HelloRequest.newBuilder()
.setName(name)
.build();
HelloReply response = stub.sayHello(request);
logger.info("Greeting: " + response.getMessage());
}
// ※ 参考
service Greeter {
rpc SayHello (HelloRequest) returns (HelloReply) {}
}
アクセス先や通信方法を表す
ManagedChannelオブジェクトを生成
Analytics Innovation Company
©BrainPad Inc.
Strictly Confidential
19
クライアントサイドの実装
private ManagedChannel channel = ManagedChannelBuilder
.forAddress(HOST, PORT)
.usePlaintext(true).build();
private GreeterGrpc.GreeterBlockingStub stub =
GreeterGrpc.newBlockingStub(channel);
public void greet(String name) {
HelloRequest request = HelloRequest.newBuilder()
.setName(name)
.build();
HelloReply response = stub.sayHello(request);
logger.info("Greeting: " + response.getMessage());
}
// ※ 参考
service Greeter {
rpc SayHello (HelloRequest) returns (HelloReply) {}
}
サービスのスタブを作成
Analytics Innovation Company
©BrainPad Inc.
Strictly Confidential
20
クライアントサイドの実装
private ManagedChannel channel = ManagedChannelBuilder
.forAddress(HOST, PORT)
.usePlaintext(true).build();
private GreeterGrpc.GreeterBlockingStub stub =
GreeterGrpc.newBlockingStub(channel);
public void greet(String name) {
HelloRequest request = HelloRequest.newBuilder()
.setName(name)
.build();
HelloReply response = stub.sayHello(request);
logger.info("Greeting: " + response.getMessage());
}
// ※ 参考
service Greeter {
rpc SayHello (HelloRequest) returns (HelloReply) {}
}
リクエストのオブジェクトを
構築
Analytics Innovation Company
©BrainPad Inc.
Strictly Confidential
21
クライアントサイドの実装
private ManagedChannel channel = ManagedChannelBuilder
.forAddress(HOST, PORT)
.usePlaintext(true).build();
private GreeterGrpc.GreeterBlockingStub stub =
GreeterGrpc.newBlockingStub(channel);
public void greet(String name) {
HelloRequest request = HelloRequest.newBuilder()
.setName(name)
.build();
HelloReply response = stub.sayHello(request);
logger.info("Greeting: " + response.getMessage());
}
// ※ 参考
service Greeter {
rpc SayHello (HelloRequest) returns (HelloReply) {}
}
rpc呼び出し
Analytics Innovation Company
©BrainPad Inc.
Strictly Confidential
22
GKEとは
Analytics Innovation Company
©BrainPad Inc.
Strictly Confidential
23
GKEとは
• コンテナ化されたアプリケーションをデプロイするためのマネージド環境
• Kubernetesのクラスタを自動でセットアップしてくれる
• GCPとのネイティブな連携
• アクセス制御
• モニタリング・ロギング
• ネットワーク・ファイアウォール・ロードバランサ 等
Analytics Innovation Company
©BrainPad Inc.
Strictly Confidential
24
GKEとは
Node Node Node
Pod
Container
Container
Cluster
Pod
Container
Container
Pod
Container
Analytics Innovation Company
©BrainPad Inc.
Strictly Confidential
25
GKEとは
Node Node Node
Pod
Container
Container
Cluster
Pod
Container
Container
Pod
Container
Container … Kubernetes上で実行する
Dockerコンテナ
Analytics Innovation Company
©BrainPad Inc.
Strictly Confidential
26
GKEとは
Node Node Node
Pod
Container
Container
Cluster
Pod
Container
Container
Pod
Container
Pod … クラスタ上で動作するプロセスに対応
いくつかのコンテナをまとめられる
Analytics Innovation Company
©BrainPad Inc.
Strictly Confidential
27
GKEとは
Node Node Node
Pod
Container
Container
Cluster
Pod
Container
Container
Pod
Container
Node … Podが動作する環境
VMだったり物理的なマシンだったり
実装上のTips
Analytics Innovation Company
©BrainPad Inc.
Strictly Confidential
29
ヘルスチェック
Analytics Innovation Company
©BrainPad Inc.
Strictly Confidential
30
ヘルスチェック
• Kubernetesでは2種類のヘルスチェック機能が存在
• Liveness チェック … プロセスが稼働しているか
• 失敗したらPodは再起動
• Readiness チェック … リクエストを受け入れる準備が整ったか
• 成功するまでリクエストが割り当てられない
• httpのリクエストかコマンド実行によるチェックしかサポートされていない
• → gRPCでのチェックはサポートされていない…
• → ヘルスチェック用のEndPointを用意→gRPCの動作チェック
• LogNet / grpc-spring-boot-starter を利用するとgRPCとHTTP
のサーバを簡単に立てられて便利
Analytics Innovation Company
©BrainPad Inc.
Strictly Confidential
31
ヘルスチェック
@RestController
@RequestMapping("/health")
public class HealthCheck {
@RequestMapping(method = RequestMethod.GET)
public String get() {
// gRPCのサービス呼び出し
stub.healthCheck();
return "OK";
}
}
Analytics Innovation Company
©BrainPad Inc.
Strictly Confidential
32
ヘルスチェック
@RestController
@RequestMapping("/health")
public class HealthCheck {
@RequestMapping(method = RequestMethod.GET)
public String get() {
// gRPCのサービス呼び出し
stub.healthCheck();
return "OK";
}
}
Readinessチェックと
Livenessチェックの内容は同じ
Analytics Innovation Company
©BrainPad Inc.
Strictly Confidential
33
ヘルスチェック
@RestController
@RequestMapping("/health")
public class HealthCheck {
@RequestMapping(method = RequestMethod.GET)
public String get() {
// gRPCのサービス呼び出し
stub.healthCheck();
return "OK";
}
}
spring-boot-web-starter → 8080
grpc-spring-boot-starter → 6565
Analytics Innovation Company
©BrainPad Inc.
Strictly Confidential
34
ヘルスチェック
@RestController
@RequestMapping("/health")
public class HealthCheck {
@RequestMapping(method = RequestMethod.GET)
public String get() {
// gRPCのサービス呼び出し
stub.healthCheck();
return "OK";
}
}
ここで(DBアクセス等を伴う)
gRPCサービスの呼び出し
Analytics Innovation Company
©BrainPad Inc.
Strictly Confidential
35
ヘルスチェック
spec:
template:
spec:
containers:
- livenessProbe:
httpGet:
path: /health
port: 8080
initialDelaySeconds: 200
periodSeconds: 10
readinessProbe:
httpGet:
path: /health
port: 8080
initialDelaySeconds: 30
periodSeconds: 5
Analytics Innovation Company
©BrainPad Inc.
Strictly Confidential
36
ヘルスチェック
spec:
template:
spec:
containers:
- livenessProbe:
httpGet:
path: /health
port: 8080
initialDelaySeconds: 200
periodSeconds: 10
readinessProbe:
httpGet:
path: /health
port: 8080
initialDelaySeconds: 30
periodSeconds: 5
Livenessチェックの設定
Analytics Innovation Company
©BrainPad Inc.
Strictly Confidential
37
ヘルスチェック
spec:
template:
spec:
containers:
- livenessProbe:
httpGet:
path: /health
port: 8080
initialDelaySeconds: 200
periodSeconds: 10
readinessProbe:
httpGet:
path: /health
port: 8080
initialDelaySeconds: 30
periodSeconds: 5
initialDelaySeconds … 200秒待ってから
最初のチェックを行う
periodSeconds … チェックの間隔
Analytics Innovation Company
©BrainPad Inc.
Strictly Confidential
38
ヘルスチェック
spec:
template:
spec:
containers:
- livenessProbe:
httpGet:
path: /health
port: 8080
initialDelaySeconds: 200
periodSeconds: 10
readinessProbe:
httpGet:
path: /health
port: 8080
initialDelaySeconds: 30
periodSeconds: 5
Readinessチェックの設定
Analytics Innovation Company
©BrainPad Inc.
Strictly Confidential
39
エラーの受け渡し
Analytics Innovation Company
©BrainPad Inc.
Strictly Confidential
40
エラーの受け渡し
• StreamObserver.onErrorを利用する
public void sayHello(HelloRequest request,
StreamObserver<HelloResponse> responseObserver) {
try {
// …
} catch (Exception e) {
responseObserver.onError(Status.INTERNAL
.withDescription(“an error occurred”)
.withCause(e) // causeはクライアントへは送信されない
.asException());
}
}
Analytics Innovation Company
©BrainPad Inc.
Strictly Confidential
41
エラーの受け渡し
利用可能なステータス (io.grpc.Status)
OK
CANCELLED
UNKNOWN
INVALID_ARGUMENT
DEADLINE_EXCEEDED
NOT_FOUND
ALREADY_EXISTS
PERMISSION_DENIED
RESOURCE_EXHAUSTED
FAILED_PRECONDITION
ABORTED
OUT_OF_RANGE
UNIMPLEMENTED
INTERNAL
UNAVAILABLE
DATA_LOSS
UNAUTHENTICATED
Analytics Innovation Company
©BrainPad Inc.
Strictly Confidential
42
エラーの受け渡し
* クライアント側ではRpcErrorの例外として受け取れる (Pythonの場合)
try:
stub.SayHello(request)
Except grpc.RpcError as e:
e.code() # => StatusCode.INTERNAL
e.details() # => “an error accurred”
Analytics Innovation Company
©BrainPad Inc.
Strictly Confidential
43
シャットダウン
Analytics Innovation Company
©BrainPad Inc.
Strictly Confidential
44
シャットダウン
• Podは様々なタイミングで終了する
• Rolling update, オートスケール, kubectlコマンド
→ 処理中のリクエストが完了してからシャットダウンしたい!
Analytics Innovation Company
©BrainPad Inc.
Strictly Confidential
45
シャットダウン
•方針
• gRPCのリクエストにタイムアウトを設定する(例: 60秒)
• ※ gRPCではクライアント側でタイムアウトを設定
• PodのterminationGracePeriodSecondsを長めに設定する
(例: 90秒)
• 各コンテナのpreStopでタイムアウトまで待つ
Analytics Innovation Company
©BrainPad Inc.
Strictly Confidential
46
シャットダウン
• gRPCのリクエストにタイムアウトを設定する
public void greet(String name) {
HelloRequest request = HelloRequest.newBuilder()
.setName(name)
.build();
HelloReply response = stub.withDeadlineAfter(60L, TimeUnit.SECONDS)
.sayHello(request);
logger.info("Greeting: " + response.getMessage());
}
Analytics Innovation Company
©BrainPad Inc.
Strictly Confidential
47
シャットダウン
• PodのterminationGracePeriodSecondsを長めに設定する(例: 90秒)
• 各コンテナのpreStopでタイムアウトまで待つ
spec:
template:
spec:
terminationGracePeriodSeconds: 90
containers:
lifecycle:
preStop:
exec:
command: ["sh", "-c", "sleep 60"]
Analytics Innovation Company
©BrainPad Inc.
Strictly Confidential
48
シャットダウン
リクエスト
sleep 終了処理
60sec
Pod削除フロー開始
90sec
Pod削除フロー開始から
90秒経つとkill
削除フロー開始前に受け付けた
リクエストはsleep中にタイムアウト
Analytics Innovation Company
©BrainPad Inc.
Strictly Confidential
49
オブジェクトの変換
Analytics Innovation Company
©BrainPad Inc.
Strictly Confidential
50
Java <-> protobuf 変換
• 既存のシステムにgRPCの機能を追加したかった
• 既存クラス
• → .proto定義
• → javaコード生成
• → 既存クラスと.protoから生成されたクラス間のコンバート
• ⇒ 既存クラスから.protoファイルとコンバータを自動生成する処理を自前で実装した
• BAData / protobuf-converter などもある
既存クラス .proto
生成された
クラス
Analytics Innovation Company
©BrainPad Inc.
Strictly Confidential
51
Java <-> protobuf 変換
• Protocol Bufferには継承を表現するような機能はない
• “Don't go looking for facilities similar to class inheritance, though – protocol
buffers don't do that.” – Protocol Buffers / Basics: Java
Analytics Innovation Company
©BrainPad Inc.
Strictly Confidential
52
Java <-> protobuf 変換
nullの扱いに注意
• Protocol Bufferのmessage型はuser.hasBirthDay()のようにhas{フィールド名}で値を持
つか知ることができる
• → false なら null
• 文字列や数値などのプリミティブな型はhas{フィールド名}が利用できない
• → wrappers.proto
• Enumもhas{フィールド名}が利用できない
• → .protoファイルを生成する際にnullを表す要素も生成する
// wrappers.proto
message StringValue {
// The string value.
string value = 1;
}
message Sample {
string s1 = 1;
StringValue s2 = 2;
}
Analytics Innovation Company
©BrainPad Inc.
Strictly Confidential
53
まとめ
• gRPCとGKEについて紹介
• 実際の開発で工夫した点や苦労した点を紹介
• ヘルスチェック, エラー処理, シャットダウン, 変換処理…
• 日本語、JavaでのgRPC, GKEの情報が増える一助になれば!
Analytics Innovation Company
©BrainPad Inc.
Strictly Confidential
54
最後に
We Are Hiring!
本資料は、未刊行文書として日本及び各国の著作権法に基づき保護されております。本資料には、株式会社ブレインパッド所有の特定情報が
含まれており、これら情報に基づく本資料の内容は、御社以外の第三者に開示されること、また、本資料を評価する以外の目的で、その一部ま
たは全文を複製、使用、公開することは、禁止されています。また、株式会社ブレインパッドによる書面での許可なく、それら情報の一部または全
文を使用または公開することは、いかなる場合も禁じられております。
株式会社ブレインパッド
〒108-0071 東京都港区白金台3-2-10 白金台ビル
TEL:03-6721-7002 FAX:03-6721-7010
www.brainpad.co.jp info@brainpad.co.jp
Analytics Innovation Company

Más contenido relacionado

Similar a GKEとgRPCで実装する多言語対応・スケーラブルな内部API

Google App Engine for Java
Google App Engine for JavaGoogle App Engine for Java
Google App Engine for JavaTakuya Tsuchida
 
JavaOne 2015 報告会 @ 東京 「About MVC 1.0 & JSON-P」
JavaOne 2015 報告会 @ 東京 「About MVC 1.0 & JSON-P」JavaOne 2015 報告会 @ 東京 「About MVC 1.0 & JSON-P」
JavaOne 2015 報告会 @ 東京 「About MVC 1.0 & JSON-P」Hiroyuki Ohnaka
 
ソーシャルアプリ勉強会(第一回資料)配布用
ソーシャルアプリ勉強会(第一回資料)配布用ソーシャルアプリ勉強会(第一回資料)配布用
ソーシャルアプリ勉強会(第一回資料)配布用Yatabe Terumasa
 
Selenium webdriver使ってみようず
Selenium webdriver使ってみようずSelenium webdriver使ってみようず
Selenium webdriver使ってみようずOda Shinsuke
 
勉強会force#4 Chatter Integration
勉強会force#4 Chatter Integration勉強会force#4 Chatter Integration
勉強会force#4 Chatter IntegrationKazuki Nakajima
 
Spring BootでHello Worldのその先へ
Spring BootでHello Worldのその先へSpring BootでHello Worldのその先へ
Spring BootでHello Worldのその先へMasatoshi Fujino
 
System3 search
System3 searchSystem3 search
System3 searchJun Chiba
 
Spring integration概要
Spring integration概要Spring integration概要
Spring integration概要kuroiwa
 
Elasticsearchプラグインの作り方
Elasticsearchプラグインの作り方Elasticsearchプラグインの作り方
Elasticsearchプラグインの作り方Shinsuke Sugaya
 
JapanDreamin24_はじめてのGraphQL×LWC.pptx
JapanDreamin24_はじめてのGraphQL×LWC.pptxJapanDreamin24_はじめてのGraphQL×LWC.pptx
JapanDreamin24_はじめてのGraphQL×LWC.pptxRyota Tabuse
 
OpenShiftでJBoss EAP構築
OpenShiftでJBoss EAP構築OpenShiftでJBoss EAP構築
OpenShiftでJBoss EAP構築Daein Park
 
NGINX New Features (Japanese Webinar)
NGINX New Features (Japanese Webinar)NGINX New Features (Japanese Webinar)
NGINX New Features (Japanese Webinar)NGINX, Inc.
 
Container Storage Interface のすべて
Container Storage Interface のすべてContainer Storage Interface のすべて
Container Storage Interface のすべて祐司 伊藤
 
Kubernete Meetup Tokyo #18 - Kubebuilder/controller-runtime 入門
Kubernete Meetup Tokyo #18 - Kubebuilder/controller-runtime 入門Kubernete Meetup Tokyo #18 - Kubebuilder/controller-runtime 入門
Kubernete Meetup Tokyo #18 - Kubebuilder/controller-runtime 入門Preferred Networks
 
Pro aspnetmvc3framework chap15
Pro aspnetmvc3framework chap15Pro aspnetmvc3framework chap15
Pro aspnetmvc3framework chap15Hideki Hashizume
 
Dartでサーバレスサービス
DartでサーバレスサービスDartでサーバレスサービス
Dartでサーバレスサービスcch-robo
 
Angular js はまりどころ
Angular js はまりどころAngular js はまりどころ
Angular js はまりどころAyumi Goto
 

Similar a GKEとgRPCで実装する多言語対応・スケーラブルな内部API (20)

Google App Engine for Java
Google App Engine for JavaGoogle App Engine for Java
Google App Engine for Java
 
JavaOne 2015 報告会 @ 東京 「About MVC 1.0 & JSON-P」
JavaOne 2015 報告会 @ 東京 「About MVC 1.0 & JSON-P」JavaOne 2015 報告会 @ 東京 「About MVC 1.0 & JSON-P」
JavaOne 2015 報告会 @ 東京 「About MVC 1.0 & JSON-P」
 
WebRTC on Native App
WebRTC on Native AppWebRTC on Native App
WebRTC on Native App
 
Gwt1
Gwt1Gwt1
Gwt1
 
ソーシャルアプリ勉強会(第一回資料)配布用
ソーシャルアプリ勉強会(第一回資料)配布用ソーシャルアプリ勉強会(第一回資料)配布用
ソーシャルアプリ勉強会(第一回資料)配布用
 
Selenium webdriver使ってみようず
Selenium webdriver使ってみようずSelenium webdriver使ってみようず
Selenium webdriver使ってみようず
 
勉強会force#4 Chatter Integration
勉強会force#4 Chatter Integration勉強会force#4 Chatter Integration
勉強会force#4 Chatter Integration
 
Spring BootでHello Worldのその先へ
Spring BootでHello Worldのその先へSpring BootでHello Worldのその先へ
Spring BootでHello Worldのその先へ
 
System3 search
System3 searchSystem3 search
System3 search
 
Spring integration概要
Spring integration概要Spring integration概要
Spring integration概要
 
Elasticsearchプラグインの作り方
Elasticsearchプラグインの作り方Elasticsearchプラグインの作り方
Elasticsearchプラグインの作り方
 
JapanDreamin24_はじめてのGraphQL×LWC.pptx
JapanDreamin24_はじめてのGraphQL×LWC.pptxJapanDreamin24_はじめてのGraphQL×LWC.pptx
JapanDreamin24_はじめてのGraphQL×LWC.pptx
 
OpenShiftでJBoss EAP構築
OpenShiftでJBoss EAP構築OpenShiftでJBoss EAP構築
OpenShiftでJBoss EAP構築
 
NGINX New Features (Japanese Webinar)
NGINX New Features (Japanese Webinar)NGINX New Features (Japanese Webinar)
NGINX New Features (Japanese Webinar)
 
Container Storage Interface のすべて
Container Storage Interface のすべてContainer Storage Interface のすべて
Container Storage Interface のすべて
 
Kubernete Meetup Tokyo #18 - Kubebuilder/controller-runtime 入門
Kubernete Meetup Tokyo #18 - Kubebuilder/controller-runtime 入門Kubernete Meetup Tokyo #18 - Kubebuilder/controller-runtime 入門
Kubernete Meetup Tokyo #18 - Kubebuilder/controller-runtime 入門
 
Pro aspnetmvc3framework chap15
Pro aspnetmvc3framework chap15Pro aspnetmvc3framework chap15
Pro aspnetmvc3framework chap15
 
gRPCurlDotNet.pptx
gRPCurlDotNet.pptxgRPCurlDotNet.pptx
gRPCurlDotNet.pptx
 
Dartでサーバレスサービス
DartでサーバレスサービスDartでサーバレスサービス
Dartでサーバレスサービス
 
Angular js はまりどころ
Angular js はまりどころAngular js はまりどころ
Angular js はまりどころ
 

Más de BrainPad Inc.

Business utilization of real estate image classification system using deep le...
Business utilization of real estate image classification system using deep le...Business utilization of real estate image classification system using deep le...
Business utilization of real estate image classification system using deep le...BrainPad Inc.
 
ブレインパッドにおける機械学習プロジェクトの進め方
ブレインパッドにおける機械学習プロジェクトの進め方ブレインパッドにおける機械学習プロジェクトの進め方
ブレインパッドにおける機械学習プロジェクトの進め方BrainPad Inc.
 
機械学習システムのアーキテクチャアラカルト
機械学習システムのアーキテクチャアラカルト機械学習システムのアーキテクチャアラカルト
機械学習システムのアーキテクチャアラカルトBrainPad Inc.
 
機械学習システム開発案件の事例紹介
機械学習システム開発案件の事例紹介機械学習システム開発案件の事例紹介
機械学習システム開発案件の事例紹介BrainPad Inc.
 
れこめん道~とあるエンジニアの苦闘の日々
れこめん道~とあるエンジニアの苦闘の日々 れこめん道~とあるエンジニアの苦闘の日々
れこめん道~とあるエンジニアの苦闘の日々 BrainPad Inc.
 
DMPの分析機能を実現する技術
DMPの分析機能を実現する技術DMPの分析機能を実現する技術
DMPの分析機能を実現する技術BrainPad Inc.
 
機械学習システムを受託開発 する時に気をつけておきたい事
機械学習システムを受託開発 する時に気をつけておきたい事機械学習システムを受託開発 する時に気をつけておきたい事
機械学習システムを受託開発 する時に気をつけておきたい事BrainPad Inc.
 
システム開発素人が深層学習を用いた画像認識で麻雀点数計算するLINEbotを作ったハナシ
システム開発素人が深層学習を用いた画像認識で麻雀点数計算するLINEbotを作ったハナシシステム開発素人が深層学習を用いた画像認識で麻雀点数計算するLINEbotを作ったハナシ
システム開発素人が深層学習を用いた画像認識で麻雀点数計算するLINEbotを作ったハナシBrainPad Inc.
 
Python研修の作り方 - teaching-is_learning-
Python研修の作り方 - teaching-is_learning-Python研修の作り方 - teaching-is_learning-
Python研修の作り方 - teaching-is_learning-BrainPad Inc.
 
2018 builderscon airflowを用いて、 複雑大規模なジョブフロー管理 に立ち向かう
2018 builderscon airflowを用いて、 複雑大規模なジョブフロー管理 に立ち向かう2018 builderscon airflowを用いて、 複雑大規模なジョブフロー管理 に立ち向かう
2018 builderscon airflowを用いて、 複雑大規模なジョブフロー管理 に立ち向かうBrainPad Inc.
 
2018.08.21-機械学習工学研究会 現場を交えた勉強会発表資料
2018.08.21-機械学習工学研究会 現場を交えた勉強会発表資料2018.08.21-機械学習工学研究会 現場を交えた勉強会発表資料
2018.08.21-機械学習工学研究会 現場を交えた勉強会発表資料BrainPad Inc.
 
実証実験報告セミナー資料 20180328(抜粋版)
実証実験報告セミナー資料 20180328(抜粋版)実証実験報告セミナー資料 20180328(抜粋版)
実証実験報告セミナー資料 20180328(抜粋版)BrainPad Inc.
 
エンジニア勉強会資料_⑥エンジニアが主導する組織マネジメントや開発体制の継続的改善
エンジニア勉強会資料_⑥エンジニアが主導する組織マネジメントや開発体制の継続的改善エンジニア勉強会資料_⑥エンジニアが主導する組織マネジメントや開発体制の継続的改善
エンジニア勉強会資料_⑥エンジニアが主導する組織マネジメントや開発体制の継続的改善BrainPad Inc.
 
エンジニア勉強会資料_⑤広告プロダクトとプラットフォームの開発
エンジニア勉強会資料_⑤広告プロダクトとプラットフォームの開発エンジニア勉強会資料_⑤広告プロダクトとプラットフォームの開発
エンジニア勉強会資料_⑤広告プロダクトとプラットフォームの開発BrainPad Inc.
 
エンジニア勉強会資料_④Rtoaster×Myndエンジンによる興味キーワード分析機能開発事例
エンジニア勉強会資料_④Rtoaster×Myndエンジンによる興味キーワード分析機能開発事例エンジニア勉強会資料_④Rtoaster×Myndエンジンによる興味キーワード分析機能開発事例
エンジニア勉強会資料_④Rtoaster×Myndエンジンによる興味キーワード分析機能開発事例BrainPad Inc.
 
エンジニア勉強会資料_③Rtoasterの11年
エンジニア勉強会資料_③Rtoasterの11年エンジニア勉強会資料_③Rtoasterの11年
エンジニア勉強会資料_③Rtoasterの11年BrainPad Inc.
 
エンジニア勉強会資料_②エンジニア・デザイナ・プロダクトオーナーが推薦するプロトタイプドリブン開発
エンジニア勉強会資料_②エンジニア・デザイナ・プロダクトオーナーが推薦するプロトタイプドリブン開発エンジニア勉強会資料_②エンジニア・デザイナ・プロダクトオーナーが推薦するプロトタイプドリブン開発
エンジニア勉強会資料_②エンジニア・デザイナ・プロダクトオーナーが推薦するプロトタイプドリブン開発BrainPad Inc.
 
エンジニア勉強会資料_①ブレインパッドの中で僕たちは何を開発しているのか?
エンジニア勉強会資料_①ブレインパッドの中で僕たちは何を開発しているのか?エンジニア勉強会資料_①ブレインパッドの中で僕たちは何を開発しているのか?
エンジニア勉強会資料_①ブレインパッドの中で僕たちは何を開発しているのか?BrainPad Inc.
 
Big Data Analytics Tokyo講演資料
Big Data Analytics Tokyo講演資料Big Data Analytics Tokyo講演資料
Big Data Analytics Tokyo講演資料BrainPad Inc.
 

Más de BrainPad Inc. (20)

Oss LT会_20210203
Oss LT会_20210203Oss LT会_20210203
Oss LT会_20210203
 
Business utilization of real estate image classification system using deep le...
Business utilization of real estate image classification system using deep le...Business utilization of real estate image classification system using deep le...
Business utilization of real estate image classification system using deep le...
 
ブレインパッドにおける機械学習プロジェクトの進め方
ブレインパッドにおける機械学習プロジェクトの進め方ブレインパッドにおける機械学習プロジェクトの進め方
ブレインパッドにおける機械学習プロジェクトの進め方
 
機械学習システムのアーキテクチャアラカルト
機械学習システムのアーキテクチャアラカルト機械学習システムのアーキテクチャアラカルト
機械学習システムのアーキテクチャアラカルト
 
機械学習システム開発案件の事例紹介
機械学習システム開発案件の事例紹介機械学習システム開発案件の事例紹介
機械学習システム開発案件の事例紹介
 
れこめん道~とあるエンジニアの苦闘の日々
れこめん道~とあるエンジニアの苦闘の日々 れこめん道~とあるエンジニアの苦闘の日々
れこめん道~とあるエンジニアの苦闘の日々
 
DMPの分析機能を実現する技術
DMPの分析機能を実現する技術DMPの分析機能を実現する技術
DMPの分析機能を実現する技術
 
機械学習システムを受託開発 する時に気をつけておきたい事
機械学習システムを受託開発 する時に気をつけておきたい事機械学習システムを受託開発 する時に気をつけておきたい事
機械学習システムを受託開発 する時に気をつけておきたい事
 
システム開発素人が深層学習を用いた画像認識で麻雀点数計算するLINEbotを作ったハナシ
システム開発素人が深層学習を用いた画像認識で麻雀点数計算するLINEbotを作ったハナシシステム開発素人が深層学習を用いた画像認識で麻雀点数計算するLINEbotを作ったハナシ
システム開発素人が深層学習を用いた画像認識で麻雀点数計算するLINEbotを作ったハナシ
 
Python研修の作り方 - teaching-is_learning-
Python研修の作り方 - teaching-is_learning-Python研修の作り方 - teaching-is_learning-
Python研修の作り方 - teaching-is_learning-
 
2018 builderscon airflowを用いて、 複雑大規模なジョブフロー管理 に立ち向かう
2018 builderscon airflowを用いて、 複雑大規模なジョブフロー管理 に立ち向かう2018 builderscon airflowを用いて、 複雑大規模なジョブフロー管理 に立ち向かう
2018 builderscon airflowを用いて、 複雑大規模なジョブフロー管理 に立ち向かう
 
2018.08.21-機械学習工学研究会 現場を交えた勉強会発表資料
2018.08.21-機械学習工学研究会 現場を交えた勉強会発表資料2018.08.21-機械学習工学研究会 現場を交えた勉強会発表資料
2018.08.21-機械学習工学研究会 現場を交えた勉強会発表資料
 
実証実験報告セミナー資料 20180328(抜粋版)
実証実験報告セミナー資料 20180328(抜粋版)実証実験報告セミナー資料 20180328(抜粋版)
実証実験報告セミナー資料 20180328(抜粋版)
 
エンジニア勉強会資料_⑥エンジニアが主導する組織マネジメントや開発体制の継続的改善
エンジニア勉強会資料_⑥エンジニアが主導する組織マネジメントや開発体制の継続的改善エンジニア勉強会資料_⑥エンジニアが主導する組織マネジメントや開発体制の継続的改善
エンジニア勉強会資料_⑥エンジニアが主導する組織マネジメントや開発体制の継続的改善
 
エンジニア勉強会資料_⑤広告プロダクトとプラットフォームの開発
エンジニア勉強会資料_⑤広告プロダクトとプラットフォームの開発エンジニア勉強会資料_⑤広告プロダクトとプラットフォームの開発
エンジニア勉強会資料_⑤広告プロダクトとプラットフォームの開発
 
エンジニア勉強会資料_④Rtoaster×Myndエンジンによる興味キーワード分析機能開発事例
エンジニア勉強会資料_④Rtoaster×Myndエンジンによる興味キーワード分析機能開発事例エンジニア勉強会資料_④Rtoaster×Myndエンジンによる興味キーワード分析機能開発事例
エンジニア勉強会資料_④Rtoaster×Myndエンジンによる興味キーワード分析機能開発事例
 
エンジニア勉強会資料_③Rtoasterの11年
エンジニア勉強会資料_③Rtoasterの11年エンジニア勉強会資料_③Rtoasterの11年
エンジニア勉強会資料_③Rtoasterの11年
 
エンジニア勉強会資料_②エンジニア・デザイナ・プロダクトオーナーが推薦するプロトタイプドリブン開発
エンジニア勉強会資料_②エンジニア・デザイナ・プロダクトオーナーが推薦するプロトタイプドリブン開発エンジニア勉強会資料_②エンジニア・デザイナ・プロダクトオーナーが推薦するプロトタイプドリブン開発
エンジニア勉強会資料_②エンジニア・デザイナ・プロダクトオーナーが推薦するプロトタイプドリブン開発
 
エンジニア勉強会資料_①ブレインパッドの中で僕たちは何を開発しているのか?
エンジニア勉強会資料_①ブレインパッドの中で僕たちは何を開発しているのか?エンジニア勉強会資料_①ブレインパッドの中で僕たちは何を開発しているのか?
エンジニア勉強会資料_①ブレインパッドの中で僕たちは何を開発しているのか?
 
Big Data Analytics Tokyo講演資料
Big Data Analytics Tokyo講演資料Big Data Analytics Tokyo講演資料
Big Data Analytics Tokyo講演資料
 

GKEとgRPCで実装する多言語対応・スケーラブルな内部API

  • 2. Analytics Innovation Company ©BrainPad Inc. Strictly Confidential 1 自己紹介 名前: 高橋秀平 所属: 株式会社ブレインパッド 仕事: インターネット広告関連ツール開発 Java歴: 5年くらい
  • 3. Analytics Innovation Company ©BrainPad Inc. Strictly Confidential 2 話すこと インターネット広告API呼び出しサービスを Java + GKE + gRPCで開発している経験を元に、 実際のシステム開発に関するTipsをご紹介します
  • 4. Analytics Innovation Company ©BrainPad Inc. Strictly Confidential 3 アジェンダ • gRPCとは • GKEとは • 実装上のTips • ヘルスチェック • エラーの受け渡し • シャットダウン • Java ⇔ protobuf 変換
  • 5. Analytics Innovation Company ©BrainPad Inc. Strictly Confidential 4 gRPCとは
  • 6. Analytics Innovation Company ©BrainPad Inc. Strictly Confidential 5 gRPCとは • Googleによって開発され、2015年にオープンソース化されたRPCフレームワーク • HTTP/2 による通信 • Protocol Buffer を IDL として採用 • クライアント・サーバともに Java, go, Python 等複数言語に対応 • 高速かつ高機能 • Cloud Native Computing Foundationの6番目のプロジェクト • Google Ads API (beta) では JSON REST形式の他にgRPC形式をサポート
  • 7. Analytics Innovation Company ©BrainPad Inc. Strictly Confidential 6 gRPCとは • 利用の流れ • .protoファイルにサービスやデータの定義を記述する • .protoファイルから各言語のソースコードを生成する • サーバサイド・クライアントサイドを実装する
  • 8. Analytics Innovation Company ©BrainPad Inc. Strictly Confidential 7 サービスやデータの定義 // サービスの定義 service Greeter { // Sends a greeting rpc SayHello (HelloRequest) returns (HelloReply) {} } // リクエスト・レスポンスの型の定義 message HelloRequest { string name = 1; } message HelloReply { string message = 1; }
  • 9. Analytics Innovation Company ©BrainPad Inc. Strictly Confidential 8 サービスやデータの定義 // サービスの定義 service Greeter { // Sends a greeting rpc SayHello (HelloRequest) returns (HelloReply) {} } // リクエスト・レスポンスの型の定義 message HelloRequest { string name = 1; } message HelloReply { string message = 1; }
  • 10. Analytics Innovation Company ©BrainPad Inc. Strictly Confidential 9 サービスやデータの定義 // サービスの定義 service Greeter { // Sends a greeting rpc SayHello (HelloRequest) returns (HelloReply) {} } // リクエスト・レスポンスの型の定義 message HelloRequest { string name = 1; } message HelloReply { string message = 1; }
  • 11. Analytics Innovation Company ©BrainPad Inc. Strictly Confidential 10 .protoファイルから各言語のソースコードを生成する • protoc コマンドを利用 protoc --proto_path=src --java_out=build/gen src/greeter.proto • Mavenを利用している場合は os72 / protoc-jar-maven-plugin なども利用可能
  • 12. Analytics Innovation Company ©BrainPad Inc. Strictly Confidential 11 サーバサイドの実装 @GRpcService public class GreeterImpl extends GreeterGrpc.GreeterImplBase { @Override public void sayHello(HelloRequest req, StreamObserver<HelloReply> responseObserver) { HelloReply reply = HelloReply.newBuilder() .setMessage("Hello " + req.getName()) .build(); responseObserver.onNext(reply); responseObserver.onCompleted(); } // ※ 参考 service Greeter { rpc SayHello (HelloRequest) returns (HelloReply) {} }
  • 13. Analytics Innovation Company ©BrainPad Inc. Strictly Confidential 12 サーバサイドの実装 @GRpcService public class GreeterImpl extends GreeterGrpc.GreeterImplBase { @Override public void sayHello(HelloRequest req, StreamObserver<HelloReply> responseObserver) { HelloReply reply = HelloReply.newBuilder() .setMessage("Hello " + req.getName()) .build(); responseObserver.onNext(reply); responseObserver.onCompleted(); } // ※ 参考 service Greeter { rpc SayHello (HelloRequest) returns (HelloReply) {} } .protoで定義したServiceに対応した クラスが生成される
  • 14. Analytics Innovation Company ©BrainPad Inc. Strictly Confidential 13 サーバサイドの実装 @GRpcService public class GreeterImpl extends GreeterGrpc.GreeterImplBase { @Override public void sayHello(HelloRequest req, StreamObserver<HelloReply> responseObserver) { HelloReply reply = HelloReply.newBuilder() .setMessage("Hello " + req.getName()) .build(); responseObserver.onNext(reply); responseObserver.onCompleted(); } // ※ 参考 service Greeter { rpc SayHello (HelloRequest) returns (HelloReply) {} } 対応するメソッドをオーバーライド
  • 15. Analytics Innovation Company ©BrainPad Inc. Strictly Confidential 14 サーバサイドの実装 @GRpcService public class GreeterImpl extends GreeterGrpc.GreeterImplBase { @Override public void sayHello(HelloRequest req, StreamObserver<HelloReply> responseObserver) { HelloReply reply = HelloReply.newBuilder() .setMessage("Hello " + req.getName()) .build(); responseObserver.onNext(reply); responseObserver.onCompleted(); } // ※ 参考 service Greeter { rpc SayHello (HelloRequest) returns (HelloReply) {} } .protoで指定した引数は第一引数 戻り値はメソッドの戻り値ではなく第二引数
  • 16. Analytics Innovation Company ©BrainPad Inc. Strictly Confidential 15 サーバサイドの実装 @GRpcService public class GreeterImpl extends GreeterGrpc.GreeterImplBase { @Override public void sayHello(HelloRequest req, StreamObserver<HelloReply> responseObserver) { HelloReply reply = HelloReply.newBuilder() .setMessage("Hello " + req.getName()) .build(); responseObserver.onNext(reply); responseObserver.onCompleted(); } // ※ 参考 service Greeter { rpc SayHello (HelloRequest) returns (HelloReply) {} } クライアントからのリクエストは reqからアクセス可能
  • 17. Analytics Innovation Company ©BrainPad Inc. Strictly Confidential 16 サーバサイドの実装 @GRpcService public class GreeterImpl extends GreeterGrpc.GreeterImplBase { @Override public void sayHello(HelloRequest req, StreamObserver<HelloReply> responseObserver) { HelloReply reply = HelloReply.newBuilder() .setMessage("Hello " + req.getName()) .build(); responseObserver.onNext(reply); responseObserver.onCompleted(); } // ※ 参考 service Greeter { rpc SayHello (HelloRequest) returns (HelloReply) {} } 戻り値はStreamObserverのonNextへ
  • 18. Analytics Innovation Company ©BrainPad Inc. Strictly Confidential 17 クライアントサイドの実装 private ManagedChannel channel = ManagedChannelBuilder .forAddress(HOST, PORT) .usePlaintext(true).build(); private GreeterGrpc.GreeterBlockingStub stub = GreeterGrpc.newBlockingStub(channel); public void greet(String name) { HelloRequest request = HelloRequest.newBuilder() .setName(name) .build(); HelloReply response = stub.sayHello(request); logger.info("Greeting: " + response.getMessage()); } // ※ 参考 service Greeter { rpc SayHello (HelloRequest) returns (HelloReply) {} }
  • 19. Analytics Innovation Company ©BrainPad Inc. Strictly Confidential 18 クライアントサイドの実装 private ManagedChannel channel = ManagedChannelBuilder .forAddress(HOST, PORT) .usePlaintext(true).build(); private GreeterGrpc.GreeterBlockingStub stub = GreeterGrpc.newBlockingStub(channel); public void greet(String name) { HelloRequest request = HelloRequest.newBuilder() .setName(name) .build(); HelloReply response = stub.sayHello(request); logger.info("Greeting: " + response.getMessage()); } // ※ 参考 service Greeter { rpc SayHello (HelloRequest) returns (HelloReply) {} } アクセス先や通信方法を表す ManagedChannelオブジェクトを生成
  • 20. Analytics Innovation Company ©BrainPad Inc. Strictly Confidential 19 クライアントサイドの実装 private ManagedChannel channel = ManagedChannelBuilder .forAddress(HOST, PORT) .usePlaintext(true).build(); private GreeterGrpc.GreeterBlockingStub stub = GreeterGrpc.newBlockingStub(channel); public void greet(String name) { HelloRequest request = HelloRequest.newBuilder() .setName(name) .build(); HelloReply response = stub.sayHello(request); logger.info("Greeting: " + response.getMessage()); } // ※ 参考 service Greeter { rpc SayHello (HelloRequest) returns (HelloReply) {} } サービスのスタブを作成
  • 21. Analytics Innovation Company ©BrainPad Inc. Strictly Confidential 20 クライアントサイドの実装 private ManagedChannel channel = ManagedChannelBuilder .forAddress(HOST, PORT) .usePlaintext(true).build(); private GreeterGrpc.GreeterBlockingStub stub = GreeterGrpc.newBlockingStub(channel); public void greet(String name) { HelloRequest request = HelloRequest.newBuilder() .setName(name) .build(); HelloReply response = stub.sayHello(request); logger.info("Greeting: " + response.getMessage()); } // ※ 参考 service Greeter { rpc SayHello (HelloRequest) returns (HelloReply) {} } リクエストのオブジェクトを 構築
  • 22. Analytics Innovation Company ©BrainPad Inc. Strictly Confidential 21 クライアントサイドの実装 private ManagedChannel channel = ManagedChannelBuilder .forAddress(HOST, PORT) .usePlaintext(true).build(); private GreeterGrpc.GreeterBlockingStub stub = GreeterGrpc.newBlockingStub(channel); public void greet(String name) { HelloRequest request = HelloRequest.newBuilder() .setName(name) .build(); HelloReply response = stub.sayHello(request); logger.info("Greeting: " + response.getMessage()); } // ※ 参考 service Greeter { rpc SayHello (HelloRequest) returns (HelloReply) {} } rpc呼び出し
  • 23. Analytics Innovation Company ©BrainPad Inc. Strictly Confidential 22 GKEとは
  • 24. Analytics Innovation Company ©BrainPad Inc. Strictly Confidential 23 GKEとは • コンテナ化されたアプリケーションをデプロイするためのマネージド環境 • Kubernetesのクラスタを自動でセットアップしてくれる • GCPとのネイティブな連携 • アクセス制御 • モニタリング・ロギング • ネットワーク・ファイアウォール・ロードバランサ 等
  • 25. Analytics Innovation Company ©BrainPad Inc. Strictly Confidential 24 GKEとは Node Node Node Pod Container Container Cluster Pod Container Container Pod Container
  • 26. Analytics Innovation Company ©BrainPad Inc. Strictly Confidential 25 GKEとは Node Node Node Pod Container Container Cluster Pod Container Container Pod Container Container … Kubernetes上で実行する Dockerコンテナ
  • 27. Analytics Innovation Company ©BrainPad Inc. Strictly Confidential 26 GKEとは Node Node Node Pod Container Container Cluster Pod Container Container Pod Container Pod … クラスタ上で動作するプロセスに対応 いくつかのコンテナをまとめられる
  • 28. Analytics Innovation Company ©BrainPad Inc. Strictly Confidential 27 GKEとは Node Node Node Pod Container Container Cluster Pod Container Container Pod Container Node … Podが動作する環境 VMだったり物理的なマシンだったり
  • 30. Analytics Innovation Company ©BrainPad Inc. Strictly Confidential 29 ヘルスチェック
  • 31. Analytics Innovation Company ©BrainPad Inc. Strictly Confidential 30 ヘルスチェック • Kubernetesでは2種類のヘルスチェック機能が存在 • Liveness チェック … プロセスが稼働しているか • 失敗したらPodは再起動 • Readiness チェック … リクエストを受け入れる準備が整ったか • 成功するまでリクエストが割り当てられない • httpのリクエストかコマンド実行によるチェックしかサポートされていない • → gRPCでのチェックはサポートされていない… • → ヘルスチェック用のEndPointを用意→gRPCの動作チェック • LogNet / grpc-spring-boot-starter を利用するとgRPCとHTTP のサーバを簡単に立てられて便利
  • 32. Analytics Innovation Company ©BrainPad Inc. Strictly Confidential 31 ヘルスチェック @RestController @RequestMapping("/health") public class HealthCheck { @RequestMapping(method = RequestMethod.GET) public String get() { // gRPCのサービス呼び出し stub.healthCheck(); return "OK"; } }
  • 33. Analytics Innovation Company ©BrainPad Inc. Strictly Confidential 32 ヘルスチェック @RestController @RequestMapping("/health") public class HealthCheck { @RequestMapping(method = RequestMethod.GET) public String get() { // gRPCのサービス呼び出し stub.healthCheck(); return "OK"; } } Readinessチェックと Livenessチェックの内容は同じ
  • 34. Analytics Innovation Company ©BrainPad Inc. Strictly Confidential 33 ヘルスチェック @RestController @RequestMapping("/health") public class HealthCheck { @RequestMapping(method = RequestMethod.GET) public String get() { // gRPCのサービス呼び出し stub.healthCheck(); return "OK"; } } spring-boot-web-starter → 8080 grpc-spring-boot-starter → 6565
  • 35. Analytics Innovation Company ©BrainPad Inc. Strictly Confidential 34 ヘルスチェック @RestController @RequestMapping("/health") public class HealthCheck { @RequestMapping(method = RequestMethod.GET) public String get() { // gRPCのサービス呼び出し stub.healthCheck(); return "OK"; } } ここで(DBアクセス等を伴う) gRPCサービスの呼び出し
  • 36. Analytics Innovation Company ©BrainPad Inc. Strictly Confidential 35 ヘルスチェック spec: template: spec: containers: - livenessProbe: httpGet: path: /health port: 8080 initialDelaySeconds: 200 periodSeconds: 10 readinessProbe: httpGet: path: /health port: 8080 initialDelaySeconds: 30 periodSeconds: 5
  • 37. Analytics Innovation Company ©BrainPad Inc. Strictly Confidential 36 ヘルスチェック spec: template: spec: containers: - livenessProbe: httpGet: path: /health port: 8080 initialDelaySeconds: 200 periodSeconds: 10 readinessProbe: httpGet: path: /health port: 8080 initialDelaySeconds: 30 periodSeconds: 5 Livenessチェックの設定
  • 38. Analytics Innovation Company ©BrainPad Inc. Strictly Confidential 37 ヘルスチェック spec: template: spec: containers: - livenessProbe: httpGet: path: /health port: 8080 initialDelaySeconds: 200 periodSeconds: 10 readinessProbe: httpGet: path: /health port: 8080 initialDelaySeconds: 30 periodSeconds: 5 initialDelaySeconds … 200秒待ってから 最初のチェックを行う periodSeconds … チェックの間隔
  • 39. Analytics Innovation Company ©BrainPad Inc. Strictly Confidential 38 ヘルスチェック spec: template: spec: containers: - livenessProbe: httpGet: path: /health port: 8080 initialDelaySeconds: 200 periodSeconds: 10 readinessProbe: httpGet: path: /health port: 8080 initialDelaySeconds: 30 periodSeconds: 5 Readinessチェックの設定
  • 40. Analytics Innovation Company ©BrainPad Inc. Strictly Confidential 39 エラーの受け渡し
  • 41. Analytics Innovation Company ©BrainPad Inc. Strictly Confidential 40 エラーの受け渡し • StreamObserver.onErrorを利用する public void sayHello(HelloRequest request, StreamObserver<HelloResponse> responseObserver) { try { // … } catch (Exception e) { responseObserver.onError(Status.INTERNAL .withDescription(“an error occurred”) .withCause(e) // causeはクライアントへは送信されない .asException()); } }
  • 42. Analytics Innovation Company ©BrainPad Inc. Strictly Confidential 41 エラーの受け渡し 利用可能なステータス (io.grpc.Status) OK CANCELLED UNKNOWN INVALID_ARGUMENT DEADLINE_EXCEEDED NOT_FOUND ALREADY_EXISTS PERMISSION_DENIED RESOURCE_EXHAUSTED FAILED_PRECONDITION ABORTED OUT_OF_RANGE UNIMPLEMENTED INTERNAL UNAVAILABLE DATA_LOSS UNAUTHENTICATED
  • 43. Analytics Innovation Company ©BrainPad Inc. Strictly Confidential 42 エラーの受け渡し * クライアント側ではRpcErrorの例外として受け取れる (Pythonの場合) try: stub.SayHello(request) Except grpc.RpcError as e: e.code() # => StatusCode.INTERNAL e.details() # => “an error accurred”
  • 44. Analytics Innovation Company ©BrainPad Inc. Strictly Confidential 43 シャットダウン
  • 45. Analytics Innovation Company ©BrainPad Inc. Strictly Confidential 44 シャットダウン • Podは様々なタイミングで終了する • Rolling update, オートスケール, kubectlコマンド → 処理中のリクエストが完了してからシャットダウンしたい!
  • 46. Analytics Innovation Company ©BrainPad Inc. Strictly Confidential 45 シャットダウン •方針 • gRPCのリクエストにタイムアウトを設定する(例: 60秒) • ※ gRPCではクライアント側でタイムアウトを設定 • PodのterminationGracePeriodSecondsを長めに設定する (例: 90秒) • 各コンテナのpreStopでタイムアウトまで待つ
  • 47. Analytics Innovation Company ©BrainPad Inc. Strictly Confidential 46 シャットダウン • gRPCのリクエストにタイムアウトを設定する public void greet(String name) { HelloRequest request = HelloRequest.newBuilder() .setName(name) .build(); HelloReply response = stub.withDeadlineAfter(60L, TimeUnit.SECONDS) .sayHello(request); logger.info("Greeting: " + response.getMessage()); }
  • 48. Analytics Innovation Company ©BrainPad Inc. Strictly Confidential 47 シャットダウン • PodのterminationGracePeriodSecondsを長めに設定する(例: 90秒) • 各コンテナのpreStopでタイムアウトまで待つ spec: template: spec: terminationGracePeriodSeconds: 90 containers: lifecycle: preStop: exec: command: ["sh", "-c", "sleep 60"]
  • 49. Analytics Innovation Company ©BrainPad Inc. Strictly Confidential 48 シャットダウン リクエスト sleep 終了処理 60sec Pod削除フロー開始 90sec Pod削除フロー開始から 90秒経つとkill 削除フロー開始前に受け付けた リクエストはsleep中にタイムアウト
  • 50. Analytics Innovation Company ©BrainPad Inc. Strictly Confidential 49 オブジェクトの変換
  • 51. Analytics Innovation Company ©BrainPad Inc. Strictly Confidential 50 Java <-> protobuf 変換 • 既存のシステムにgRPCの機能を追加したかった • 既存クラス • → .proto定義 • → javaコード生成 • → 既存クラスと.protoから生成されたクラス間のコンバート • ⇒ 既存クラスから.protoファイルとコンバータを自動生成する処理を自前で実装した • BAData / protobuf-converter などもある 既存クラス .proto 生成された クラス
  • 52. Analytics Innovation Company ©BrainPad Inc. Strictly Confidential 51 Java <-> protobuf 変換 • Protocol Bufferには継承を表現するような機能はない • “Don't go looking for facilities similar to class inheritance, though – protocol buffers don't do that.” – Protocol Buffers / Basics: Java
  • 53. Analytics Innovation Company ©BrainPad Inc. Strictly Confidential 52 Java <-> protobuf 変換 nullの扱いに注意 • Protocol Bufferのmessage型はuser.hasBirthDay()のようにhas{フィールド名}で値を持 つか知ることができる • → false なら null • 文字列や数値などのプリミティブな型はhas{フィールド名}が利用できない • → wrappers.proto • Enumもhas{フィールド名}が利用できない • → .protoファイルを生成する際にnullを表す要素も生成する // wrappers.proto message StringValue { // The string value. string value = 1; } message Sample { string s1 = 1; StringValue s2 = 2; }
  • 54. Analytics Innovation Company ©BrainPad Inc. Strictly Confidential 53 まとめ • gRPCとGKEについて紹介 • 実際の開発で工夫した点や苦労した点を紹介 • ヘルスチェック, エラー処理, シャットダウン, 変換処理… • 日本語、JavaでのgRPC, GKEの情報が増える一助になれば!
  • 55. Analytics Innovation Company ©BrainPad Inc. Strictly Confidential 54 最後に We Are Hiring!
  • 56. 本資料は、未刊行文書として日本及び各国の著作権法に基づき保護されております。本資料には、株式会社ブレインパッド所有の特定情報が 含まれており、これら情報に基づく本資料の内容は、御社以外の第三者に開示されること、また、本資料を評価する以外の目的で、その一部ま たは全文を複製、使用、公開することは、禁止されています。また、株式会社ブレインパッドによる書面での許可なく、それら情報の一部または全 文を使用または公開することは、いかなる場合も禁じられております。 株式会社ブレインパッド 〒108-0071 東京都港区白金台3-2-10 白金台ビル TEL:03-6721-7002 FAX:03-6721-7010 www.brainpad.co.jp info@brainpad.co.jp Analytics Innovation Company