grpc java 项目_gRPC Java:Spring boot整合gRPC

接下来我们需要把gRPC和Spring boot整合在一起,这里主要记录我们的整合方式。

项目目录结构

项目的目录结构如下:

123456789101112131415161718

foo-svc

├── foo-svc-proto

│   ├── build.gradle

│   └── src

│   └── main

│   └── proto

│   ├── xx1_service.proto

│   └── xx2_service.proto

├── foo-svc-server

│   ├── build.gradle

│   └── src

│   └── main

│   ├── java

│   └── resources

│   └── application.yml

├── build.gradle

├── gradle.properties

└── settings.gradle

一个gRPC服务的项目由两个子项目组成:

proto项目,里面维护gRPC服务的proto文件

server项目,gRPC服务的具体实现

gradle构建脚本

整个gRPC服务项目使用gradle构建,下面介绍父子项目的各个构建脚本的内容。

根项目foo-svc

foo-svc/settings.gradle:

123

include 'foo-svc-proto'

include 'foo-svc-server'

rootProject.name = 'foo-svc'

foo-svc/build.gradle:

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465

buildscript {

repositories {

mavenCentral()

}

ext {

springBootVersion = '1.5.4.RELEASE'

}

dependencies {

classpath 'com.github.ben-manes:gradle-versions-plugin:0.11.1'

classpath 'com.google.protobuf:protobuf-gradle-plugin:0.8.1'

classpath "org.springframework.boot:spring-boot-gradle-plugin:${springBootVersion}"

}

}

apply plugin:'base'

allprojects {

group = 'com.frognew.svc'

version = version

repositories {

maven {

mavenCentral()

}

}

ext {

grpcVersion = '1.4.0'

grpcSpringBootStarterVersion = '1.1.1.RELEASE'

jasyptSpringBootStarterVersion = '1.12'

mybatisSpringBootStarterVersion = '1.3.0'

logbackVersion = '1.2.2'

slf4jVersion='1.7.25'

protocVersion='3.3.0'

}

}

subprojects {

apply plugin: 'java'

apply plugin: 'eclipse'

apply plugin: 'com.github.ben-manes.versions'

configurations {

all*.exclude group:'com.sun.xml.bind',module:'jaxb-impl'

all*.exclude group:'xml-apis',module:'xml-apis'

all*.exclude group:'stax',module:'stax-api'

all*.exclude group:'org.slf4j',module:'slf4j-log4j12'

all*.exclude group:'commons-logging'

all*.exclude group:'c3p0'

}

sourceSets.main.resources.srcDirs += "src/main/java"

sourceSets.test.resources.srcDirs += "src/test/java"

compileJava {

sourceCompatibility=1.8

targetCompatibility=1.8

options.encoding='UTF-8'

}

compileTestJava {

sourceCompatibility=1.8

targetCompatibility=1.8

options.encoding='UTF-8'

}

tasks.eclipse.dependsOn cleanEclipse

}上面根项目的构建脚本foo-svc/build.gradle中主要定义了项目通用的依赖版本和一些插件信息,并对项目的构建行为做了一些限制。

子项目foo-svc-proto

foo-svc/foo-svc-proto/build.gradle:

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263

apply plugin: 'com.google.protobuf'

apply plugin: 'maven-publish'

dependencies {

compile "io.grpc:grpc-netty:${grpcVersion}"

compile "io.grpc:grpc-protobuf:${grpcVersion}"

compile "io.grpc:grpc-stub:${grpcVersion}"

}

sourceSets {

main {

java {

srcDir 'build/generated/source/proto/main/java'

srcDir 'build/generated/source/proto/main/grpc'

}

}

}

protobuf {

protoc {

artifact = "com.google.protobuf:protoc:${protocVersion}"

}

plugins {

grpc {

artifact = "io.grpc:protoc-gen-grpc-java:${grpcVersion}"

}

}

generateProtoTasks {

all()*.plugins {

grpc {

option 'enable_deprecated=false'

}

}

}

}

jar {

exclude("*.proto")

}

task sourceJar(type: Jar) {

from sourceSets.main.allJava

}

publishing {

repositories {

maven {

url "http://192.168.1.10:8081/nexus/content/repositories/snapshots/"

}

}

publications {

mavenJava(MavenPublication) {

from components.java

artifact sourceJar {

classifier "sources"

}

}

}

}

tasks.eclipse.dependsOn compileJava

foo-svc/foo-svc-proto/build.gradle中使用com.google.protobuf插件将src/main/proto中的proto文件编译生成gRPC的java代码。

生成的代码位于build/generated/source/proto/main/java和build/generated/source/proto/main/grpc这两个目录中。

同时将这两个目录添加到了sourceSets.main.java中。使用maven-publish插件可以将构建生成的jar包发布到团队的私有maven仓库中,这样gRPC服务的java客户端可以直接使用仓库中的jar。

子项目foo-svc-server

foo-svc/foo-svc-server/build.gradle:

123456789101112131415161718

apply plugin: 'org.springframework.boot'

dependencies {

compile project(':foo-svc-proto')

compile 'org.springframework.boot:spring-boot-starter'

compile 'org.springframework.boot:spring-boot-starter-data-redis'

compile "net.devh:grpc-server-spring-boot-starter:$grpcSpringBootStarterVersion"

compile "org.mybatis.spring.boot:mybatis-spring-boot-starter:$mybatisSpringBootStarterVersion"

compile "com.github.ulisesbocchio:jasypt-spring-boot-starter:$jasyptSpringBootStarterVersion"

compile 'com.fasterxml.jackson.core:jackson-databind'

runtime 'mysql:mysql-connector-java'

runtime 'redis.clients:jedis:2.9.0'

runtime 'org.apache.commons:commons-pool2:2.4.2'

testCompile('org.springframework.boot:spring-boot-starter-test')

}

从子项目foo-svc-server的构建脚本可以看出,foo-svc-server就是一个简单的spring-boot项目。

这里使用了yidongnan/grpc-spring-boot-starter这个项目简化了Spring-boot和gRPC整合的代码。

1234567891011

@GrpcService(Xxx1ServiceGrpc.class)

public class Xxx1ServiceService extends Xxx1ServiceImplBase {

@Override

public void sayHello(SayHelloReq request, StreamObserver responseObserver) {

SayHelloResp.Builder respBuilder = SayHelloResp.newBuilder();

......

responseObserver.onNext(respBuilder.build());

responseObserver.onCompleted();

}

服务的客户端

123456789101112131415161718192021222324

import org.springframework.boot.SpringApplication;

import org.springframework.boot.autoconfigure.SpringBootApplication;

import org.springframework.context.annotation.Bean;

import com.frognew.svc.foo.proto.Xxx1ServiceGrpc;

import io.grpc.Channel;

import net.devh.springboot.autoconfigure.grpc.client.GrpcClient;

@SpringBootApplication

public class ClientDemoApplication {

@GrpcClient("foo-svc-server")

private Channel xxx1SvcChannel;

@Bean

public Xxx1ServiceGrpc.Xxx1ServiceBlockingStub xxx1ServiceBlockingStub() {

return Xxx1ServiceGrpc.newBlockingStub(xxx1SvcChannel);

}

public static void main(String[] args) {

SpringApplication.run(ApidemoApplication.class, args);

}

}

将上面的Xxx1ServiceBlockingStub注入到业务组件中直接使用即可。

上面@GrpcClient("foo-svc-server")中会读取客户端项目application.yml中的:

1234567

grpc:client:foo-svc-server:host:- 127.0.0.1port:- 9090

获取gRPC服务的地址和端口。我们的服务最终是发布到Kubernetes中,上面的host和port最终设置成Kubernetes中对应Server的名称和端口即可,服务发现机制由Kubernetes提供。

参考

你可能感兴趣的:(grpc,java,项目)