一、什么是gRPC
gRPC是一个高性能、通用的开源 RPC 框架,其由 Google 主要面向移动应用开发并基于HTTP/2协议标准而设计,基于ProtoBuf(Protocol Buffers) 序列化协议开发,且支持众多开发语言。gRPC 提供了一种简单的方法来精确地定义服务和为 iOS、Android 和后台支持服务自动生成可靠性很强的客户端功能库。客户端充分利用高级流和链接功能,从而有助于节省带宽、降低的 TCP 链接次数、节省 CPU 使用、和电池寿命。
gRPC使用 ProtoBuf 来定义服务,ProtoBuf 是由 Google 开发的一种数据序列化协议(类似于 XML、JSON、hessian)。ProtoBuf 能够将数据进行序列化,并广泛应用在数据存储、通信协议等方面。不过,当前 gRPC 仅支持 Protobuf ,且不支持在浏览器中使用。由于 gRPC 的设计能够支持支持多种数据格式。
二、首先搭建maven项目
1.然后在src/main目录下的proto目录
2.设置把proto设置成java的sources,选择file->project structure->modules
3.创建hello_service.proto的文件
4.hello_service.proto与hello.proto
4.1、hello.proto
syntax = "proto3";package com.xxx.tutorial.demo.grpc;option java_multiple_files = true;
option java_package = "com.xxx.tutorial.model";
option java_outer_classname = "Hello";message HelloRequest{ string name = 1; int32 id = 2;
}
message HelloResponse{ string message = 1;
}
4.2、hello_service.proto
syntax = "proto3";package com.xxx.tutorial.demo.grpc;option java_multiple_files = true;
option java_package = "com.xxx.tutorial.service";
option java_outer_classname = "GreetingService";import "hello.proto";service HelloService{ rpc sayHello(HelloRequest) returns (HelloResponse);
}
5.需要导入一个IDEA插件Protobuf
6.使用maven进行编译
7.选择install等待一会进行生成GRPC代码
三、应用springboot搭建GRPC项目
8.比如说创建简单的helloworld.proto
syntax = "proto3";option java_multiple_files = true;
//定义输出的目录,生成的目录就是“net/devh/examples/grpc/lib”下面
option java_package = "net.devh.examples.grpc.lib";
//定义输出的文件名称,生成在lib下的就是HelloWorldProto.class
option java_outer_classname = "HelloWorldProto";// The greeting service definition.
//定义的接口的类,这里会生成一个SimpleGrpc.class,服务端需要来实现的
service Simple {//定义接口方法rpc SayHello (HelloRequest) returns (HelloReply) {}
}//请求参数
message HelloRequest {string name = 1;
}//返回结果
message HelloReply {string message = 1;
}
9.将gradle转换成maven
注意此代码是gradle转写maven的gradle文件,并非项目文件。进行gradle打包需要将此代码注释
apply plugin: &#39;maven&#39;task writeNewPom <<{pom {project {inceptionYear &#39;2018&#39;licenses {license {name &#39;The Apache Software License, Version 2.0&#39;url &#39;http://www.apache.org/licenses/LICENSE-2.0.txt&#39;distribution &#39;repo&#39;}}}}.writeTo("pom.xml")
}
再运行右侧 gradle writeNewPom 即可在当前项目中生成pom.xml文件。
10.创建springboot的依赖
build.gradle
apply plugin: &#39;java&#39;
apply plugin: &#39;com.google.protobuf&#39;
apply plugin: &#39;idea&#39;repositories {maven { url "https://plugins.gradle.org/m2/" }
}dependencies {compile "io.grpc:grpc-netty:1.10.0"compile "io.grpc:grpc-protobuf:1.10.0"compile "io.grpc:grpc-stub:1.10.0"
}protobuf {protoc {// The artifact spec for the Protobuf Compilerartifact &#61; &#39;com.google.protobuf:protoc:3.0.0&#39;}plugins {// Optional: an artifact spec for a protoc plugin, with "grpc" as// the identifier, which can be referred to in the "plugins"// container of the "generateProtoTasks" closure.grpc {artifact &#61; &#39;io.grpc:protoc-gen-grpc-java:1.0.0-pre2&#39;}}generateProtoTasks {ofSourceSet(&#39;main&#39;)*.plugins {// Apply the "grpc" plugin whose spec is defined above, without// options. Note the braces cannot be omitted, otherwise the// plugin will not be added. This is because of the implicit way// NamedDomainObjectContainer binds the methods.grpc { }}}
}buildscript {repositories {maven { url "https://plugins.gradle.org/m2/" }}dependencies {classpath &#39;com.google.protobuf:protobuf-gradle-plugin:0.8.4&#39;}
}
进行编译
11.创建客户端项目
build.gradle
buildscript {ext {springBootVersion &#61; &#39;2.0.2.RELEASE&#39;}repositories {mavenCentral()}dependencies {classpath("org.springframework.boot:spring-boot-gradle-plugin:${springBootVersion}")}
}apply plugin: &#39;java&#39;
apply plugin: &#39;eclipse&#39;
apply plugin: &#39;org.springframework.boot&#39;
apply plugin: &#39;io.spring.dependency-management&#39;//apply plugin: &#39;maven&#39;group &#61; &#39;com.example&#39;
version &#61; &#39;0.0.1-SNAPSHOT&#39;
sourceCompatibility &#61; 1.8repositories {mavenCentral()
}dependencies {compile project(&#39;:grpc-lib&#39;)compile("net.devh:grpc-client-spring-boot-starter:1.4.0.RELEASE")compile(&#39;org.springframework.boot:spring-boot-starter-web&#39;)
}//
//task writeNewPom <<{
// pom {
// project {
// inceptionYear &#39;2018&#39;
// licenses {
// license {
// name &#39;The Apache Software License, Version 2.0&#39;
// url &#39;http://www.apache.org/licenses/LICENSE-2.0.txt&#39;
// distribution &#39;repo&#39;
// }
// }
// }
// }.writeTo("pom.xml")
//} as String
GRPCClientApplication
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;&#64;SpringBootApplication
public class GRpcClientApplication {public static void main(String[] args) {SpringApplication.run(GRpcClientApplication.class, args);}
}
GrpcClientController
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;&#64;RestController
public class GrpcClientController {&#64;Autowiredprivate GrpcClientService grpcClientService;&#64;RequestMapping("/")public String printMessage(&#64;RequestParam(defaultValue &#61; "Michael") String name) {return grpcClientService.sendMessage(name);}
}
GrpcClientService
import io.grpc.Channel;
import net.devh.examples.grpc.lib.HelloReply;
import net.devh.examples.grpc.lib.HelloRequest;
import net.devh.examples.grpc.lib.SimpleGrpc;
import net.devh.springboot.autoconfigure.grpc.client.GrpcClient;
import org.springframework.stereotype.Service;&#64;Service
public class GrpcClientService {&#64;GrpcClient("local-grpc-server")private Channel serverChannel;public String sendMessage(String name) {SimpleGrpc.SimpleBlockingStub stub &#61; SimpleGrpc.newBlockingStub(serverChannel);HelloReply response &#61; stub.sayHello(HelloRequest.newBuilder().setName(name).build());return response.getMessage();}
}
application.properties
server.port&#61;8080
spring.application.name&#61;local-grpc-client
grpc.client.local-grpc-server.host&#61;127.0.0.1
grpc.client.local-grpc-server.port&#61;9898
grpc.client.local-grpc-server.enableKeepAlive&#61;true
grpc.client.local-grpc-server.keepAliveWithoutCalls&#61;true
12.服务端项目
build.gradle
buildscript {ext {springBootVersion &#61; &#39;2.0.2.RELEASE&#39;}repositories {mavenCentral()}dependencies {classpath("org.springframework.boot:spring-boot-gradle-plugin:${springBootVersion}")}
}apply plugin: &#39;java&#39;
apply plugin: &#39;eclipse&#39;
apply plugin: &#39;org.springframework.boot&#39;
apply plugin: &#39;io.spring.dependency-management&#39;group &#61; &#39;com.example&#39;
version &#61; &#39;0.0.1-SNAPSHOT&#39;
sourceCompatibility &#61; 1.8repositories {mavenCentral()
}dependencies {compile(&#39;org.springframework.boot:spring-boot-starter-web&#39;)compile &#39;net.devh:grpc-server-spring-boot-starter:1.4.0.RELEASE&#39;//注意&#xff0c;需要依赖grpc-lib项目compile project(&#39;:grpc-lib&#39;)testCompile(&#39;org.springframework.boot:spring-boot-starter-test&#39;)
}
buildscript {dependencies {classpath("org.springframework.boot:spring-boot-gradle-plugin:0.8.4")}
}
GRpcApplication
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;&#64;SpringBootApplication
public class GRpcApplication {public static void main(String[] args) {SpringApplication.run(GRpcApplication.class, args);}
}
GrpcServerService
import io.grpc.stub.StreamObserver;
import net.devh.examples.grpc.lib.HelloReply;
import net.devh.examples.grpc.lib.HelloRequest;
import net.devh.examples.grpc.lib.SimpleGrpc;
import net.devh.springboot.autoconfigure.grpc.server.GrpcService;&#64;GrpcService(SimpleGrpc.class)
public class GrpcServerService extends SimpleGrpc.SimpleImplBase{&#64;Overridepublic void sayHello(HelloRequest req, StreamObserver
}
application.properties
#服务端名称
spring.application.name&#61;local-grpc-server
#服务端运行端口
server.port&#61;8888
#grpc通信端口
grpc.server.port&#61;9898
13.大功告成。
14.待续…
15.https://github.com/863473007/springboot-gRPC/tree/master/springboot-grpc