【橘子分布式】gRPC(番外篇-拦截器)

一、简介

我们之前其实已经完成了关于grpc的一些基础用法,实际上还有一些比较相对进阶的使用方式。比如:

  • 拦截器:包括客户端和服务端的拦截器,进而在每一端都可以划分为流式的拦截器和非流式的拦截器。和以前我们在spring web中的拦截器思路是一样的,都可以在请求来之前做一些统一的处理,进而减少代码量,做一些鉴权 ,数据校验 ,限流等等,和业务解耦。
    gRPC的拦截器
    1. 一元请求的 拦截器
      客户端 【请求 响应】
      服务端 【请求 响应】
    2. 流式请求的 拦截器 (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模块。

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值