rustum 发表于 2022-2-18 09:37

干货!有图有真相——基于http2.0协议的通信框架grpc

定义


remote procedure call,远程过程调用,grpc即是这样一款应用程序之间通信的框架,基于http2.0协议,遵循server/client模型,高性能、开源和通用
优点

grpc通过protobuf文件来定义类以及接口,所以有非常严格的条件约束grpc是基于http2.0协议的,参数传输过程中,会把数据序列化为二进制编码,这样会大大减少传输数据的数据量,从而可以很大程度上提高性能grpc可以方便的支持流式通信(理论上通过http2.0就可以使用streaming模式)
缺点

不支持分布式客户端和服务端都要依赖基于protobuf编写而编译的公共模块
使用场景

需要对传参有严格条件约束的对性能有更高要求时
简单案例

创建公共依赖模块grpc-common,定义protobuf文件

pom文件引入相关依赖

<properties>      <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>      <maven.compiler.source>1.8</maven.compiler.source>      <maven.compiler.target>1.8</maven.compiler.target>      <grpc.version>1.37.0</grpc.version>      <protobuf.version>3.16.0</protobuf.version>    </properties>    <dependencies>      <!--protobuf工具类-->      <dependency>            <groupId>com.google.protobuf</groupId>            <artifactId>protobuf-java-util</artifactId>            <version>${protobuf.version}</version>      </dependency>      <!--grpc相关依赖-->      <dependency>            <groupId>io.grpc</groupId>            <artifactId>grpc-stub</artifactId>            <version>${grpc.version}</version>      </dependency>      <dependency>            <groupId>io.grpc</groupId>            <artifactId>grpc-protobuf</artifactId>            <version>${grpc.version}</version>      </dependency>      <dependency>            <groupId>io.grpc</groupId>            <artifactId>grpc-netty</artifactId>            <version>${grpc.version}</version>      </dependency>      <dependency>            <groupId>jakarta.annotation</groupId>            <artifactId>jakarta.annotation-api</artifactId>            <version>1.3.5</version>      </dependency>    </dependencies>    <build>      <extensions>            <extension>                <groupId>kr.motd.maven</groupId>                <artifactId>os-maven-plugin</artifactId>                <version>1.5.0.Final</version>            </extension>      </extensions>      <plugins>            <plugin>                <groupId>org.xolstice.maven.plugins</groupId>                <artifactId>protobuf-maven-plugin</artifactId>                <version>0.6.1</version>                <extensions>true</extensions>                <configuration>                  <protocArtifact>com.google.protobuf:protoc:${protobuf.version}:exe:${os.detected.classifier}</protocArtifact>                  <pluginId>grpc-java</pluginId>                  <pluginArtifact>io.grpc:protoc-gen-grpc-java:${grpc.version}:exe:${os.detected.classifier}</pluginArtifact>                </configuration>                <executions>                  <execution>                        <goals>                            <goal>compile</goal>                            <goal>compile-custom</goal>                        </goals>                  </execution>                </executions>            </plugin>      </plugins>    </build>定义Hello.proto

syntax = "proto3";option java_multiple_files = true;package com.lyj.grpc.service;import public "google/protobuf/timestamp.proto";import "google/protobuf/any.proto";message People {string name = 1;google.protobuf.Timestamp createDate = 2;}message RspsMsg {string bizCode = 1;string bizDesc = 2;google.protobuf.Any data = 3;}service HelloService {rpc sayhello(People) returns (RspsMsg);}使用protobuf插件进行编译


image.png

创建服务端

pom文件引入依赖

    <properties>      <java.version>1.8</java.version>      <grpc-common.version>0.0.1-SNAPSHOT</grpc-common.version>      <net.devh.grpc.version>2.12.0.RELEASE</net.devh.grpc.version>    </properties>    <dependencies>      <dependency>            <groupId>com.example</groupId>            <artifactId>grpc-common</artifactId>            <version>${grpc-common.version}</version>      </dependency>      <dependency>            <groupId>net.devh</groupId>            <artifactId>grpc-server-spring-boot-starter</artifactId>            <version>${net.devh.grpc.version}</version>      </dependency>    </dependencies>修改配置文件application.properties

spring.application.name=grpc-servergrpc.server.port=9090创建服务端代码HelloGrpcServicelmpl.java

package com.example.grpcserver.grpc.server;import com.google.protobuf.Timestamp;import com.lyj.grpc.service.HelloServiceGrpc;import com.lyj.grpc.service.People;import com.lyj.grpc.service.RspsMsg;import io.grpc.stub.StreamObserver;import lombok.extern.slf4j.Slf4j;import net.devh.boot.grpc.server.service.GrpcService;/*** * grpc服务端 * @author: liyajie * @version: 1.0 * @date: 2021/07/07 15:13 */@GrpcService@Slf4jpublic class HelloGrpcServicelmpl extends HelloServiceGrpc.HelloServiceImplBase {    public void sayhello(People people, StreamObserver<RspsMsg> responseObserver){      RspsMsg.Builder builder = RspsMsg.newBuilder();      String name = people.getName();      Timestamp timestamp = people.getCreateDate();      responseObserver.onNext(builder.setBizCode("0000").setBizDesc(name + "在" + timestamp + "时间给你说hello").build());      responseObserver.onCompleted();    }}创建客户端

pom文件引入依赖

<properties>      <java.version>1.8</java.version>      <grpc-common.version>0.0.1-SNAPSHOT</grpc-common.version>      <net.devh.grpc.version>2.12.0.RELEASE</net.devh.grpc.version>    </properties>    <dependencies>      <dependency>            <groupId>org.springframework.boot</groupId>            <artifactId>spring-boot-starter</artifactId>      </dependency>      <dependency>            <groupId>org.springframework.boot</groupId>            <artifactId>spring-boot-starter-test</artifactId>            <scope>test</scope>      </dependency>      <dependency>            <groupId>org.projectlombok</groupId>            <artifactId>lombok</artifactId>      </dependency>      <dependency>            <groupId>net.devh</groupId>            <artifactId>grpc-client-spring-boot-starter</artifactId>            <version>${net.devh.grpc.version}</version>      </dependency>      <dependency>            <groupId>com.example</groupId>            <artifactId>grpc-common</artifactId>            <version>${grpc-common.version}</version>      </dependency>    </dependencies>创建客户端代码HelloGrpcClient.java

package com.example.grpcclient.grpc.client;import com.example.grpcclient.entity.People;import com.google.protobuf.util.Timestamps;import com.lyj.grpc.service.HelloServiceGrpc;import com.lyj.grpc.service.RspsMsg;import io.grpc.Channel;import lombok.extern.slf4j.Slf4j;import net.devh.boot.grpc.client.inject.GrpcClient;import org.springframework.stereotype.Service;/*** * TODO * @author: liyajie * @version: 1.0 * @date: 2021/07/07 16:01 */@Service@Slf4jpublic class HelloGrpcClient {    @GrpcClient("grpc-server")    private Channel channel;    public StringsayHello(People request){      HelloServiceGrpc.HelloServiceBlockingStub helloServiceBlockingStub = HelloServiceGrpc.newBlockingStub(channel);      com.lyj.grpc.service.People people = com.lyj.grpc.service.People.newBuilder().setName(request.getName())                .setCreateDate(Timestamps.fromMillis(request.getCreateDate().getTime()))                .build();      RspsMsg rspsMsg = helloServiceBlockingStub.sayhello(people);      return "sayHello:" + rspsMsg.getBizCode();    }}修改配置文件application.properties

spring.application.name=grpc-clientserver.port=9091grpc.client.grpc-server.address=static://localhost:9090grpc.client.grpc-server.enableKeepAlive=truegrpc.client.grpc-server.keepAliveWithoutCalls=truegrpc.client.grpc-server.negotiationType=plaintext创建测试实体类People.java

package com.example.grpcclient.entity;import lombok.Data;import java.util.Date;/*** * TODO * @author: liyajie * @version: 1.0 * @date: 2021/07/07 16:12 */@Datapublic class People {    private String name;    private Date createDate;}创建测试GrpcTestController.java

package com.example.grpcclient.controller;import com.example.grpcclient.entity.People;import com.example.grpcclient.grpc.client.HelloGrpcClient;import org.springframework.beans.factory.annotation.Autowired;import org.springframework.web.bind.annotation.GetMapping;import org.springframework.web.bind.annotation.RestController;import java.util.Date;/*** * TODO * @author: liyajie * @version: 1.0 * @date: 2021/07/07 16:02 */@RestControllerpublic class GrpcTestController {    @Autowired    HelloGrpcClient helloGrpcClient;    @GetMapping("/grpcTest")    public String grpcTest(){      People people = new People();      people.setName("张三");      people.setCreateDate(new Date());      return helloGrpcClient.sayHello(people);    }}分别启动服务端和客户端,使用postman进行测试


image.png
页: [1]
查看完整版本: 干货!有图有真相——基于http2.0协议的通信框架grpc