gRPC是一项进程间通信技术,可以用来连接、调用、操作和调试分布式异构应用程序。
在开发gRPC应用程序时,先要定义服务接口,其中应包含
消费者消费服务的方式
消费者能够远程调用的方法
调用这些方法所使用的参数和消息格式等
在服务定义中所使用的语言叫作接口定义语言(interface definition language,IDL)。服务定义
基于gPRC的生产者和消费者

当调用gRPC服务时,客户端的gRPC库会使用protocol buffers,并将RPC的请求编排(marshal)为protocol buffers格式,然后将其通过HTTP/2进行发送。在服务器端,请求会被解排(unmarshal),对应的过程调用会使用protocol buffers来执行。
gPRC劣势
创建接口模块grpc-demo:grpc-api。 grpc的版本一定要与protobuf匹配
apply plugin: "io.spring.dependency-management"
dependencyManagement {
imports {
mavenBom "io.grpc:grpc-bom:1.43.0"
}
}
//==============protobuf配置================
sourceSets {
main {
proto {
srcDir 'src/main/proto'
}
}
test {
proto {
srcDir 'src/test/proto'
}
}
}
protobuf {
protoc {
//从仓库下载
artifact = 'com.google.protobuf:protoc:3.19.1'
//生成代码的目录
generatedFilesBaseDir = "$projectDir/src/"
plugins {
grpc {
artifact = "io.grpc:protoc-gen-grpc-java:1.43.0"
}
}
generateProtoTasks {
//protobuf源码输出目录
all().each { task ->
task.builtins {
java {
outputSubDir = 'grpc'
}
}
}
//grpc源码输出目录
all()*.plugins {
grpc {
outputSubDir = 'grpc'
}
}
}
}
}
//==============protobuf配置================
//在build之前执行proto代码生成
build.dependsOn(":grpc-demo:grpc-api:generateProto")
clean {
delete protobuf.generatedFilesBaseDir + "/main/grpc"
}
dependencies {
compile 'com.google.protobuf:protobuf-java-util:3.19.1'
compile 'com.google.protobuf:protobuf-java:3.19.1'
compile 'io.grpc:grpc-stub'
compile 'io.grpc:grpc-protobuf'
}
使用Protocol Buffers来定义服务接口,新建一个HelloService.proto文件,放在grpc-demo/grpc-api/src/main/proto/HelloService.proto目录下
syntax="proto3";
option java_multiple_files = true;
package cn.jannal.grpc.facade.dto;
message HelloRequest {
string firstName = 1;
string lastName = 2;
}
message HelloResponse {
string greeting = 1;
}
service HelloService {
rpc hello(HelloRequest) returns (HelloResponse);
}
新建grpc-demo:grpc-provider模块
apply plugin: "io.spring.dependency-management"
dependencyManagement {
imports {
mavenBom "io.grpc:grpc-bom:1.43.0"
}
}
dependencies {
compile project(":grpc-demo:grpc-api")
compile 'io.grpc:grpc-netty-shaded'
compile 'io.grpc:grpc-protobuf'
compile 'io.grpc:grpc-stub'
compile "io.grpc:grpc-services" // reflection
}
新建GrpcProvider
@Slf4j
public class GrpcProvider {
public static void main(String[] args) throws IOException {
int port = 8081;
ServerBuilder serverBuilder = ServerBuilder
.forPort(port)
.addService(new HelloServiceImpl());
Server server = serverBuilder.build();
Runtime.getRuntime().addShutdownHook(new Thread(() -> {
if (server != null) {
server.shutdown();
}
log.info("Server Shutdown!");
}));
serverBuilder.intercept(TransmitStatusRuntimeExceptionInterceptor.instance());
server.start();
log.info("Server start port {} !", port);
startDaemonAwaitThread(server);
}
private static void startDaemonAwaitThread(Server server) {
Thread awaitThread = new Thread(() -> {
try {
server.awaitTermination();
} catch (InterruptedException ignore) {
}
});
awaitThread.setDaemon(false);
awaitThread.start();
}
}
新建grpc-demo:grpc-consumer模块
apply plugin: "io.spring.dependency-management"
dependencyManagement {
imports {
mavenBom "io.grpc:grpc-bom:1.43.0"
}
}
dependencies {
compile project(":grpc-demo:grpc-api")
compile 'io.grpc:grpc-netty-shaded'
compile 'io.grpc:grpc-protobuf'
compile 'io.grpc:grpc-stub'
compile "io.grpc:grpc-services" // reflection
}
同步调用
@Slf4j
public class GrpcConsumer {
public static final String IP = "127.0.0.1";
public static final int PORT = 8081;
public static void doFuture() throws Exception {
ManagedChannel channel = ManagedChannelBuilder.forAddress(IP, PORT)
.usePlaintext()// 启用明文
.build();
HelloServiceGrpc.HelloServiceFutureStub stub = HelloServiceGrpc.newFutureStub(channel);
ListenableFuture<HelloResponse> future = stub.hello(HelloRequest.newBuilder()
.setFirstName("Jannal")
.setLastName("Jan")
.build());
HelloResponse helloResponse = future.get();
log.info("服务端响应:{}", helloResponse);
}
public static void main(String[] args) throws Exception {
doSync();
}
}
异步调用
public static void doASyncCallback() {
ManagedChannel channel = ManagedChannelBuilder.forAddress(IP, PORT)
.usePlaintext()
.build();
HelloServiceGrpc.HelloServiceStub stub = HelloServiceGrpc.newStub(channel);
stub.hello(HelloRequest.newBuilder()
.setFirstName("Jannal")
.setLastName("Jan")
.build(), new StreamObserver<HelloResponse>() {
@Override
public void onNext(HelloResponse helloResponse) {
log.info("服务端响应:{}", helloResponse);
try {
sleep(10);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
@Override
public void onError(Throwable t) {
}
@Override
public void onCompleted() {
}
});
}
Future方式(可异步转同步)
public static void doFuture() throws Exception {
ManagedChannel channel = ManagedChannelBuilder.forAddress(IP, PORT)
.usePlaintext()// 启用明文
.build();
HelloServiceGrpc.HelloServiceFutureStub stub = HelloServiceGrpc.newFutureStub(channel);
ListenableFuture<HelloResponse> future = stub.hello(HelloRequest.newBuilder()
.setFirstName("Jannal")
.setLastName("Jan")
.build());
HelloResponse helloResponse = future.get();
log.info("服务端响应:{}", helloResponse);
}