一、简介
我们之前其实已经完成了关于grpc的一些基础用法,实际上还有一些比较相对进阶的使用方式。比如:
- 拦截器:包括客户端和服务端的拦截器,进而在每一端都可以划分为流式的拦截器和非流式的拦截器。和以前我们在spring web中的拦截器思路是一样的,都可以在请求来之前做一些统一的处理,进而减少代码量,做一些鉴权 ,数据校验 ,限流等等,和业务解耦。
gRPC的拦截器- 一元请求的 拦截器
客户端 【请求 响应】
服务端 【请求 响应】 - 流式请求的 拦截器 (Stream Tracer)
客户端 【请求 响应】
服务端 【请求 响应】
- 一元请求的 拦截器
- 客户端重试:grpc的客户端还可以发起重试请求,当我们有一些异常并非代码异常的时候,可以通过重试来避免问题。
- NameResolver :当用于微服务的时候,需要注册中心对服务名的解析等等。
- 负载均衡:包括(pick-first , 轮训)等轮训方式。
- 可以在其他微服务框架中整合,比如dubbo中,spring cloud中,用protobuf来序列化数据,用grpc来发起rpc(比如可以替代open fegin)等场合。
下面我们就来从拦截器功能开始学习一下grpc。
二、项目构建
我们为进阶篇搭建一个新的工程。结构还是客户端,服务端,api模块。
其中api模块作为公共内容被其他模块引入做公共的声明使用。
api模块: rpc-grpc-adv-api
服务端模块:rpc-grpc-adv-server
客户端模块: rpc-grpc-adv-client
1、api模块
<dependencies>
<dependency>
<groupId>io.grpc</groupId>
<artifactId>grpc-netty-shaded</artifactId>
<version>1.51.0</version>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>io.grpc</groupId>
<artifactId>grpc-protobuf</artifactId>
<version>1.51.0</version>
</dependency>
<dependency>
<groupId>io.grpc</groupId>
<artifactId>grpc-stub</artifactId>
<version>1.51.0</version>
</dependency>
<dependency> <!-- necessary for Java 9+ -->
<groupId>org.apache.tomcat</groupId>
<artifactId>annotations-api</artifactId>
<version>6.0.53</version>
<scope>provided</scope>
</dependency>
</dependencies>
<build>
<extensions>
<extension>
<groupId>kr.motd.maven</groupId>
<artifactId>os-maven-plugin</artifactId>
<version>1.7.1</version>
</extension>
</extensions>
<plugins>
<plugin>
<groupId>org.xolstice.maven.plugins</groupId>
<artifactId>protobuf-maven-plugin</artifactId>
<version>0.6.1</version>
<configuration>
<protocArtifact>com.google.protobuf:protoc:3.21.7:exe:${os.detected.classifier}</protocArtifact>
<pluginId>grpc-java</pluginId>
<pluginArtifact>io.grpc:protoc-gen-grpc-java:1.52.1:exe:${os.detected.classifier}</pluginArtifact>
<outputDirectory>${basedir}/src/main/java</outputDirectory>
<clearOutputDirectory>false</clearOutputDirectory>
</configuration>
<executions>
<execution>
<goals>
<goal>compile</goal>
<goal>compile-custom</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
在main目录下创建proto目录,下建立Hello.proto文件,声明内容为。
syntax = "proto3";
package com.levi;
option java_multiple_files = false;
option java_package = "com.levi";
option java_outer_classname = "HelloProto";
message HelloRequest{
string name = 1;
}
message HelloRespnose{
string result = 1;
}
service HelloService{
// 普通方法
rpc hello(HelloRequest) returns (HelloRespnose);
// 双端流方法
rpc hello1(stream HelloRequest) returns (stream HelloRespnose);
}
然后通过编译器编译生成对应的message类HelloProto.java和service类HelloServiceGrpc.java。
然后该模块将会被其他模块引用,使用这些定义的类。
2、server模块
引入api模块。
<dependencies>
<dependency>
<groupId>com.levi</groupId>
<artifactId>rpc-grpc-adv-api</artifactId>
<version>1.0-SNAPSHOT</version>
</dependency>
</dependencies>
服务端业务代码为:
@Slf4j
public class HelloServiceImpl extends HelloServiceGrpc.HelloServiceImplBase {
@Override
public void hello(HelloProto.HelloRequest request, StreamObserver<HelloProto.HelloRespnose> responseObserver) {
String name = request.getName();
System.out.println("接收到客户端的参数name = " + name);
responseObserver.onNext(HelloProto.HelloRespnose.newBuilder().setResult("this is server result").build());
responseObserver.onCompleted();
}
}
服务端启动代码为:
package com.levi;
import com.levi.service.HelloServiceImpl;
import io.grpc.Server;
import io.grpc.ServerBuilder;
import java.io.IOException;
public class GrpcServer {
public static void main(String[] args) throws InterruptedException, IOException {
ServerBuilder<?> serverBuilder = ServerBuilder.forPort(9000);
serverBuilder.addService(new HelloServiceImpl());
Server server = serverBuilder.build();
server.start();
server.awaitTermination();
}
}
3、client模块
引入api模块。

最低0.47元/天 解锁文章
812

被折叠的 条评论
为什么被折叠?



