gRPCをつかったSpring Bootアプリケーションをつくってみる
概要
gRPCに興味があったので、Spring Bootを使ったサンプルアプリケーションを実装してみました。
gRPCとは
詳しくは、Guides | gRPC をみてください。
という特徴があります。
gRPCを利用することで、通信の高速化が期待できたり、仕様からコードを自動生成することができ、開発のコストを下げることできます。
以降は、Spring BootアプリケーションでgRPCを導入した手順について書いていきます。
やったこと
やったことは、以下の通りです。
- Springプロジェクトの作成
- build.gradleの修正
- .protoファイルの作成
- 自動生成
- gRPCサーバの実装
- gRPCクライアントの実装
- 動作確認
環境は、
Java8
Spring Boot 2.0.2.RELEASE
Gradle 4.6
です。
サンプルプログラムは以下にあります。 github.com
以下、ひとつずつ説明していきます。
Springプロジェクトの作成
まずは、Spring Initiilzrでプロジェクトを作成します。
build.gradleの修正
プロジェクトが作成できたら、build.gradleを修正します。
buildscript {
ext {
springBootVersion = '2.0.2.RELEASE'
}
repositories {
mavenCentral()
}
dependencies {
classpath("org.springframework.boot:spring-boot-gradle-plugin:${springBootVersion}")
classpath('com.google.protobuf:protobuf-gradle-plugin:0.8.3')
}
}
apply plugin: 'java'
apply plugin: 'eclipse'
apply plugin: 'org.springframework.boot'
apply plugin: 'io.spring.dependency-management'
apply plugin: 'com.google.protobuf'
group = 'com.dais39'
version = '0.0.1-SNAPSHOT'
sourceCompatibility = 1.8
repositories {
jcenter()
mavenCentral()
}
dependencies {
compile('org.springframework.boot:spring-boot-starter-web')
compile('org.lognet:grpc-spring-boot-starter:2.3.2')
testCompile('org.springframework.boot:spring-boot-starter-test')
}
protobuf {
protoc {
artifact = "com.google.protobuf:protoc:3.2.0"
}
plugins {
grpc {
artifact = 'io.grpc:protoc-gen-grpc-java:1.4.0'
}
}
generateProtoTasks {
all()*.plugins {
grpc {}
}
}
}
sourceSets {
main {
java {
srcDirs 'build/generated/source/proto/main/grpc'
srcDirs 'build/generated/source/proto/main/java'
}
}
}
.protoファイルの作成
.protoファイルを作成していきます。 gRPCでは、.protoファイルで雛形を定義しておき、それを元にgRPCサーバとクライアントのコードを自動生成する流れになります。
自動生成
gradleコマンドで.protoファイルからコードを自動生成します。
$ ./gradlew generateProto
コマンドを実行するとbuild/generated/source/proto/main/配下にgrpcとjavaパッケージが作成されていると思います。
gRPCサーバの実装
自動生成されたbuild/generated/source/proto/main/grpc/配下にあるxxxxGrpc.xxxxImplBaseクラスを継承したクラスを作成します。 Spring Bootの場合は、継承したクラスに@GRpcServiceをつけると必要な設定はSpring Bootがやってくれます。
package com.dais39.samplegrpcspringboot; import io.grpc.examples.helloworld.GreeterGrpc; import io.grpc.examples.helloworld.HelloReply; import io.grpc.examples.helloworld.HelloRequest; import io.grpc.stub.StreamObserver; import org.lognet.springboot.grpc.GRpcService; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; @SpringBootApplication public class SampleGrpcSpringbootApplication { public static void main(String[] args) { SpringApplication.run(SampleGrpcSpringbootApplication.class, args); } @GRpcService public static class GreeterService extends GreeterGrpc.GreeterImplBase { @Override public void sayHello(HelloRequest request, StreamObserver<HelloReply> responseObserver) { HelloReply reply = HelloReply.newBuilder().setMessage("Hello " + request.getName()).build(); responseObserver.onNext(reply); responseObserver.onCompleted(); } } }
gRPCクライアントの実装
gRPCサーバを呼ぶクライアントを実装します。 今回は、Spring MVCの ControllerからgRPCサーバを呼ぶよう実装してみます。
package com.dais39.samplegrpcspringboot; import io.grpc.ManagedChannel; import io.grpc.ManagedChannelBuilder; import io.grpc.examples.helloworld.GreeterGrpc; import io.grpc.examples.helloworld.HelloReply; import io.grpc.examples.helloworld.HelloRequest; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.PathVariable; import org.springframework.web.bind.annotation.RestController; @RestController public class SampleController { @GetMapping("/grpc/{name}") public String hello(@PathVariable String name) { ManagedChannel channel = ManagedChannelBuilder.forAddress("localhost", 6565) .usePlaintext(true) .build(); GreeterGrpc.GreeterBlockingStub stub = GreeterGrpc.newBlockingStub(channel); HelloRequest request = HelloRequest.newBuilder() .setName(name) .build(); HelloReply reply = stub.sayHello(request); System.out.println("Reply: " + reply); return reply.getMessage(); } }
動作確認
まず、gRPCサーバを起動し、その後、gRPCクライアントから接続します。 今回はgRPCサーバもgRPCクライアントと同時に起動できるので、↓のコマンドを実行して、ブラウザでlocalhost:8080/grpc/hoge とアクセスすると、結果が確認できると思います。
$ ./gradlew build $ java -jar build/libs/sample-grpc-springboot-0.0.1-SNAPSHOT.jar
参考資料
JavaでgRPC導入のためのポイント #Java - Qiita
Spring BootでgRPCする #SpringBoot - Qiita
GitHub - LogNet/grpc-spring-boot-starter: Spring Boot starter module for gRPC framework.