干货!有图有真相——基于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]