サーバサイドKotlinでgRPCをやってみよう

D1531f9547e24397c7e85881fac03096?s=47 Takehata Naoto
September 09, 2019

 サーバサイドKotlinでgRPCをやってみよう

2019年9月9日 「Kotlin Fest Reject Conference 2019」の発表資料です。

D1531f9547e24397c7e85881fac03096?s=128

Takehata Naoto

September 09, 2019
Tweet

Transcript

  1. サーバーサイドKotlinでgRPCをやってみよう ⽵端 尚⼈ @n_takehata 2019/9/9 Kotlin Fest Reject Conference 2019

  2. ⾃⼰紹介

  3. 概要 ⽵端 尚⼈ 所属:株式会社アプリボット 職種:バックエンドエンジニア 好きな⾔語:Kotlin Twitter:@n_takehata 2006.04 公務員 2007.12

    SES 2011.01 サイバーエージェント 2014.04 アプリボット
  4. 登壇、執筆など • CEDEC 2018、2019登壇 https://speakerdeck.com/n_takehata/cedec- 2018 • Kotlin Fest 2018登壇(LT⼤会)

    • 雑誌Software Design 2019年2〜4⽉号に てサーバーサイドKotlinについての短期連 載執筆
  5. Kotlin Fest 2019に申し込んだテーマ

  6. Kotlin × gRPCを使⽤した次世代のサーバーサイド開発

  7. Rejected…

  8. セッション⼀覧をよく⾒ると

  9. gRPCよりGraphQLなのか︕︕

  10. サーバーサイドKotlinでgRPCをやってみよう ⽵端 尚⼈ @n_takehata 2019/9/9 Kotlin Fest Reject Conference 2019

    タイトルパクりました ※ @shiraj_iさんごめんなさい
  11. 今⽇はgRPCもいいなって 思ってもらいたいです︕

  12. アジェンダ 1.gRPCとはなにか? 2.Protocol Buffersについて 3.サーバーサイドKotlinでgRPCを使うには

  13. 2019/9/9 gRPCとはなにか︖ 1

  14. gRPCとは︖ • Google製のRPCフレームワーク • HTTP/2、Protocol Bufferesを標準でサポートし、ハイパ フォーマンスな通信を実現 • RESTに代わる通信⽅式の⼀つとしても期待されている

  15. 特徴

  16. • Protocol Bufferesによるインターフェース定義共通化 • Java、C#、Goなど様々な⾔語に対応 • 各⾔語のコード⾃動⽣成が可能 • HTTP/2による⾼速で柔軟な通信

  17. パフォーマンス(RESTとの⽐較)

  18. 平均リクエスト時間 (ms) 平均レスポンス時間 (ms) gRPC 2.92 3.6 REST 7.16 12.78

    ※2018年3⽉当時の検証結果です リクエストが約2倍、レスポンスが約4倍速かった (条件付き)
  19. 2019/9/9 Protocol Buffersについて 2

  20. Protocol Buffersとは︖ • 通信のインターフェースを定義できるIDLの⼀種 • protocというコマンドで、定義ファイルからインターフェース に合わせた様々な⾔語のコードを⽣成できる (Java、C#、C++、Python、Go、Ruby、PHP、Dart) • 定義した構造のバイナリデータで通信する

  21. サンプル

  22. ①リクエスト、レスポンスのパラメータを定義 ②APIのインターフェースを定義 .protoという拡張⼦で定義 service Greeter { rpc SayHello (HelloRequest) returns

    (HelloReply); } message HelloRequest { string name = 1; } message HelloReply { string message = 1; } ① ②
  23. 使いたい⾔語を指定してコンパイル

  24. protocコマンドの例(Golang) protoc --go_out=plugins=grpc:../pb hello.proto

  25. ⽣成されるコード • Messageのデータ構造に合わせたModelクラス • データのシリアライズ、デシリアライズ • gRPCのサーバー実装のBaseクラス(プラグイン必要) • gRPCのクライアントStub (プラグイン必要)

    • etc…
  26. コンパイルイメージ

  27. ⽣成したファイルの実⾏イメージ ⾃動⽣成のServer、Stubのプログラムを介して 通信を実装できる

  28. 通信部分の実装が容易に • 定義ファイルさえ書けば、パラメータのクラスなどを作成する ⼿間が不要 • サーバー、クライアント間の実装の齟齬も防げる • GraphQLやSwaggerとも通づる機構

  29. 2019/9/9 サーバーサイドKotlinでgRPCを使うには 2

  30. KotlinでのgRPCを使うには • ⾃動⽣成のコードはJavaで作成する(Kotlinには⾮対応) • Spring Bootを使っている場合はgrpc-spring-boot-starterを使う のが⼿軽 • コード⽣成はprotocを直接使わず、Gradleプラグインで実⾏で きる

  31. ⼿順

  32. Gradleにプラグイン、依存関係を追加 compile("io.github.lognet:grpc-spring-boot-starter:3.3.0") id("com.google.protobuf") version "0.8.9" ①Protocol Buffersをコンパイルするためのプラグイン ②Spring BootでgRPCを扱うためのStarter

  33. コードジェネレータの設定 ①使⽤するprotocのライブラリ、バージョンを指定 ②gRPCのコードを⽣成するプラグインを指定 protobuf { protoc { artifact = "com.google.protobuf:protoc:3.5.1-1"

    } plugins { grpc { artifact = "io.grpc:protoc-gen-grpc-java:${grpcVersion}" } } generateProtoTasks { all().each { task -> task.plugins { grpc } } } generatedFilesBaseDir = "$projectDir/src/" } ① ②
  34. コンパイルタスクの実⾏ generateProtoタスクがprotocを実⾏ ./gradlew generateProto

  35. ファイルが⽣成される • xxxOuterClass.java • service、messageで定義したクラスを含むクラス • シリアライズ、デシリアライズなどをやってくれる • xxxGrpc.java •

    xxxOuterClassを使⽤してgRPCで通信するサーバー処理やクライアン トStubなどを含んだクラス
  36. サーバー側のコードの実装 ①⾃動⽣成のBaseクラスを継承 ②gRPCのサービスとして起動時に読み込ませるアノテーション @GRpcService class GreeterService: GreeterGrpc.GreeterImplBase() { override fun

    sayHello(request: HelloRequest, responseObserver: StreamObserver<HelloReply>) { val replyBuilder = HelloReply.newBuilder().setMessage("Hello " + request.name) responseObserver.onNext(replyBuilder.build()) responseObserver.onCompleted() } } ① ②
  37. クライアント側のコードの実装 ①接続の設定 ②Stubのインスタンス⽣成 ③Stubのメソッド実⾏ fun execSayHello(name: String) { val request

    = HelloRequest.newBuilder().setName(name).build() val channel = ManagedChannelBuilder.forAddress("localhost", 6565).build() val stub = GreeterGrpc.newBlockingStub(channel) stub.sayHello(request) } ① ② ③
  38. まとめ

  39. サーバーサイドKotlinでgRPCを使うには • Gradleにprotobufのプラグイン、grpc-spring-boot-starterの依存関係 を追加 • protoファイルを定義しコンパイル • ⽣成されたコードを継承し、アノテーションを付けて実装 参考: https://blog.takehata-engineer.com/entry/server-side-kotlin-grpc-project-

    creation-to-start-confirmation
  40. ご清聴ありがとうございました