Grpc入门使用

本文介绍了gRPC,一个由Google开发的高性能RPC框架,其设计包括网络通信、HTTP2协议、多种语言支持和高效序列化。文章还详细讲解了ProtocolBuffers的作用以及与SpringBoot的集成,展示了gRPC在现代IT技术中的应用和优势。
摘要由CSDN通过智能技术生成

一、简介

1. gRPC 是由google开源的一个高性能的RPC框架。Stubby Google内部的RPC,演化而来的,2015正式开源。云原生时代是一个RPC标准。gRPC一款语言中立平台中立、开源的远程过程调用(RPC)系统。

2. gRPC 核心的设计思路 

A. 网络通信 ---> gRPC自己封装网络通信的部分 提供多种语言的 网络通信的封装 (C Java[Netty] GO)

B. 协议    ---> HTTP2 传输数据的时候 二进制数据内容。 支持双向流(双工)连接的多路复用。

C. 序列化   ---> 基本文本 JSON  基于二进制 Java原生序列化方式 Thrift二进制的序列化 压缩二级制序列化。
                         protobuf (Protocol Buffers) google开源一种序列化方式  时间效率和空间效率是JSON的3---5倍。IDL语言 

D. 代理的创建 --->让调用者像调用本地方法那样 去调用远端的服务方法。stub

3. gRPC 与 ThriftRPC 区别
   共性:支持异构语言的RPC。
   区别:
        1. 网络通信 Thrift TCP   专属协议
                   GRPC   HTTP2
        2. 性能角度 ThriftRPC 性能 高于 gRPC
        3. gRPC 大厂背书(Google),云原生时代 与其他组件合作的顺利。所以gRPC应用更广泛。

4. gRPC的好处 
   1. 高效的进行进程间通信。
   2. 支持多种语言 原生支持 C  Go Java实现。C语言版本上扩展 C++ C# NodeJS Python Ruby 
   3. 支持多平台运行 Linux Android IOS MacOS Windows。
   4. gPRC序列化方式采用protobuf,效率高。
   5. 使用Http2协议
   6. 大厂的背书

gRPC能够做到语言中立的原因在于,可以通过gRPC提供的编译器编译统一的proto files 文件创建gRPC服务,用protocol buffers 消息类型来定义方法和返回类型。

而服务端和客户端要调用gRPC服务,就需要这些编译成Java 或其他语言的文件。

二、Protocol Buffers 【protobuf】

protobuf 是一种与编程语言无关的 IDL 语言,与具体的平台无关。它定义的中间语言,可以方便的在client和sever中进行rpc的数据传输。

目前protobuf有2种版本, proto2 proto3,目前主流应用的都是proto3。

protobuf要安装protobuf的编译器,编译的目的,是要把protobuf的IDL语言转换为具体的某一种开发语言。

protobuf 编译器的安装

brew install protobuf 
protoc --version

protobuf 语法详解

文件格式 .proto       xxxxx.proto

指定版本 syntax = "proto3";

注释  单行 // 多行 /* */

与JAVA语言相关的语法

#后续protobuf生成的java代码 一个源文件还是多个源文件  xx.java
option java_multiple_files = false; 

#指定protobuf生成的类 放置在哪个包中
option java_package = "com.suns";

#指定的protobuf生成的外部类的名字(管理内部类【内部类才是真正开发使用】)
option java_outer_classname = "UserServce";

导入 import "xxx/UserService.proto"; 

基本类型

枚举

enum SEASON {

        SPRING = 0;

        SUMMER = 1;

}

枚举的值 必须是0开始

消息Message

message LoginReq {

        string name = 1;

        singular string password = 2;

        int32 age = 3;

}

编号从1开始,注意:19000 - 19999 不能用这个区间内的编号,因为他是protobuf自己保留的。

- singular :这个字段的值 只能是0个或者1个。 null   “111111”

- repeated :重复的,相当于java中的list

message Result {

        string content = 1;

        repeated string status = 2;

}

消息可以嵌套 
message SearchResponse{
   message Result{
      string url = 1;
      string title = 2;
   }

  string xxx = 1;
  int32  yyy = 2;
  Result ppp = 3;
}

message AAA{
  string xxx = 1;
  SearchResponse.Result yyy = 2;
}

oneof [其中一个]
message SimpleMessage{
   oneof test_oneof{
      string name = 1;
      int32  age = 2;
   }
   
   test_oneof xxx
}

定义服务

service HelloService {

        rpc hello(HelloReq) returns (HelloRes) {}

}

grpc服务4个服务方式。

三、第一个grpc开发

在API模块中,通过配置maven插件将IDL文件编译为具体语言的代码文件。

pom文件中引入grpc的依赖和配置插件,

<dependency>
                    <groupId>io.grpc</groupId>
            <artifactId>grpc-netty-shaded</artifactId>
            <version>1.61.0</version>
            <scope>runtime</scope>
        </dependency>
        <dependency>
            <groupId>io.grpc</groupId>
            <artifactId>grpc-protobuf</artifactId>
            <version>1.61.0</version>
        </dependency>
        <dependency>
            <groupId>io.grpc</groupId>
            <artifactId>grpc-stub</artifactId>
            <version>1.61.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>

<build>
        <extensions>
            <extension>
                <groupId>kr.motd.maven</groupId>
                <artifactId>os-maven-plugin</artifactId>
                <version>1.7.1</version>
            </extension>
        </extensions>
        <plugins>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-compiler-plugin</artifactId>
                <version>3.8.1</version>
                <configuration>
                    <source>8</source>
                    <target>8</target>
                </configuration>
            </plugin>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
                <version>2.1.3.RELEASE</version>
            </plugin>

            <plugin>
                <groupId>org.xolstice.maven.plugins</groupId>
                <artifactId>protobuf-maven-plugin</artifactId>
                <version>0.6.1</version>
                <configuration>
                    <protocArtifact>com.google.protobuf:protoc:3.25.1:exe:${os.detected.classifier}</protocArtifact>
                    <pluginId>grpc-java</pluginId>
                    <pluginArtifact>io.grpc:protoc-gen-grpc-java:1.61.0:exe:${os.detected.classifier}</pluginArtifact>
                </configuration>
                <executions>
                    <execution>
                        <goals>
                            <goal>compile</goal>
                            <goal>compile-custom</goal>
                        </goals>
                    </execution>
                </executions>
            </plugin>
        </plugins>
    </build>

将变异之后的文件copy到java路径下,

// 服务端实现服务
public class HelloServiceImpl extends HelloServiceGrpc.HelloServiceImplBase {
    @Override
    public void hi(HelloServiceProto.HelloReq request, StreamObserver<HelloServiceProto.HelloRes> responseObserver) {

        // 1.获取请求参数
        String name = request.getName();
        int age = request.getAge();
        System.out.println("接受到的数据:" + name + "," + age);

        // 2.业务处理和封装响应
        HelloServiceProto.HelloRes.Builder builder = HelloServiceProto.HelloRes.newBuilder();
        builder.setContent("我是grpc");
        HelloServiceProto.HelloRes res = builder.build();

        // 3.设置返回
        responseObserver.onNext(res);
        responseObserver.onCompleted();
    }
}


// 服务端注册服务
public class Server {
    public static void main(String[] args) throws InterruptedException, IOException {
        // 1.绑定端口
        ServerBuilder<?> serverBuilder = ServerBuilder.forPort(9003);
        // 2.发布服务
        serverBuilder.addService(new HelloServiceImpl());
        // 3.创建服务对象
        io.grpc.Server server = serverBuilder.build();
        server.start();
        server.awaitTermination();
    }
}


// 客户端请求服务
public class Client {
    public static void main(String[] args) {
        // 1.创建通信的管道
        ManagedChannel managedChannel = ManagedChannelBuilder.forAddress("localhost", 9003).usePlaintext().build();
        // 2.获得代理对象
        HelloServiceGrpc.HelloServiceBlockingStub helloServiceBlockingStub = HelloServiceGrpc.newBlockingStub(managedChannel);
        // 3.封装请求参数
        HelloServiceProto.HelloReq.Builder builder = HelloServiceProto.HelloReq.newBuilder();
        builder.setName("张三");
        builder.setAge(30);
        HelloServiceProto.HelloReq helloReq = builder.build();
        // 4.发起rpc调用
        HelloServiceProto.HelloRes helloRes = helloServiceBlockingStub.hi(helloReq);
        // 5.获得返回结果
        String content = helloRes.getContent();

        System.out.println("返回的内容是:" + content);

        managedChannel.shutdown();

    }
}

4种通信模式

1. 简单rpc 一元rpc (Unary RPC)  主要
2. 服务端流式RPC   (Server Streaming RPC)
3. 客户端流式RPC   (Client Streaming RPC)
4. 双向流RPC (Bi-directional Stream RPC)

不同的代理方式

1. BlockingStub
   阻塞 通信方式 (同步)
2. Stub
   异步 通过监听处理的

3. FutureStub
   同步 异步 NettyFuture
   1. FutureStub只能应用 一元RPC  

四、与spring boot的整合 

    <dependency>
        <groupId>net.devh</groupId>
        <artifactId>grpc-server-spring-boot-starter</artifactId>
        <version>2.14.0.RELEASE</version>
    </dependency>

社区已经封装了完善的spring boot starter了,可以直接拿来使用。

gRPC-Spring-Boot-Starter 文档 | grpc-spring

GitHub - grpc-ecosystem/grpc-spring: Spring Boot starter module for gRPC framework.

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值