什么是 GRPC
gRPC 是一种高性能、开源的远程过程调用(RPC)框架,由 Google 开发并公开发布。它基于 Protocol Buffers(Protobuf)作为默认的序列化和接口定义语言,并使用 HTTP/2 协议进行通信。
RPC 是一种用于不同进程或计算机之间进行通信的机制,它允许应用程序之间像调用本地函数一样进行远程调用。gRPC 提供了一种简单的方法来定义服务接口和消息格式,使开发人员能够方便地定义和使用跨语言的远程调用。
在 gRPC 中,服务接口和消息格式使用 Protobuf 进行定义。Protobuf 是一种轻量级、语言无关且可扩展的数据序列化格式,它能够将结构化数据进行编码,并通过网络在不同应用程序之间进行传输。通过使用 Protobuf,gRPC 可以自动生成与之对应的客户端和服务器端代码,简化了开发过程。
gRPC 使用 HTTP/2 作为底层的通信协议。相较于传统的 HTTP/1.1 协议,HTTP/2 提供了更低的延迟和更高的吞吐量,支持双向流通信和流控制。这使得 gRPC 能够高效地传输数据,并支持实时性要求高的应用场景。
gRPC 提供了多种语言的支持,包括 Java、C++、Python、Go、C# 等。这使开发人员可以在不同的编程语言中使用相同的定义文件和通信接口,实现跨语言的远程调用。
总之,gRPC 是一个功能强大、高性能的远程过程调用框架,通过使用 Protobuf 和 HTTP/2,它提供了简单、可靠、高效的跨语言通信机制。
SpringBoot 集成 GRPC
集成gRPC也是心血来潮,知道gRPC性能比较高,但是一直也没用过,借用这次也顺便熟悉熟悉gRPC的集成和实现。
首先明确一个概念:客户端 和 服务端
- 客户端:被调用方
- 服务端:调用方
客户端
1、Maven配置
<!-- grpc 自身服务-->
<dependency>
<groupId>net.devh</groupId>
<artifactId>grpc-server-spring-boot-starter</artifactId>
</dependency>
<build>
<!--grpc proto文件编译插件-->
<extensions>
<extension>
<groupId>kr.motd.maven</groupId>
<artifactId>os-maven-plugin</artifactId>
<version>1.6.2</version>
</extension>
</extensions>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
<!--grpc proto文件编译插件-->
<plugin>
<groupId>org.xolstice.maven.plugins</groupId>
<artifactId>protobuf-maven-plugin</artifactId>
<version>0.6.1</version>
<configuration>
<!-- 设置 protoc 的版本 -->
<protocArtifact>com.google.protobuf:protoc:3.12.0:exe:${os.detected.classifier}</protocArtifact>
<!-- 设置插件的版本 -->
<pluginId>grpc-java</pluginId>
<pluginArtifact>io.grpc:protoc-gen-grpc-java:1.34.1:exe:${os.detected.classifier}</pluginArtifact>
<!-- 设置输出目录 -->
<outputDirectory>${project.basedir}/src/main/java</outputDirectory>
<!-- 是否清除输出目录 -->
<clearOutputDirectory>false</clearOutputDirectory>
</configuration>
<executions>
<execution>
<goals>
<!-- 执行 protobuf 编译和 gRPC 插件 -->
<goal>compile</goal>
<goal>compile-custom</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
2、application.yml配置
grpc:
server:
port: 8090
3、proto 文件
创建一个 mess.proto 文件放在 src/main/proto 目录下
// proto 文件放在 src/main/proto 目录下
// 指定使用 proto3 语法
syntax = "proto3";
// 生成的 Java 代码将被拆分为多个文件
option java_multiple_files = true;
// 指定生成的 Java 代码所在的包
option java_package = "com.yanxi.yxregiserve.web.grpc.messService";
// 定义一个 gRPC 服务,名为 MessService
service MessService {
// 定义一个 gRPC 方法,名为 getHello
// 接收一个 MessRequest 参数,并返回一个 MessResponse
rpc getHello(MessRequest) returns (MessResponse) {}
}
// 定义一个接受消息类型,名为 MessRequest
message MessRequest{
string str = 1;
}
// 定义一个返回消息类型,名为 MessResponse
message MessResponse {
// 状态
int32 status = 1;
// 消息
string msg = 2;
// 数据
string data = 3;
}
4、编译
mvn compile
或者
因为子啊proto文件中配置了,所以
编译完成就会在你的 src\main\java\com\yanxi\yxregiserve\web\grpc\messService目录中出现:
这就是反编译的java代码。
5、重载
我自己的习惯,在这个位置创建一个impl文件
继承 MessServiceGrpc.MessServiceImplBase
package com.yanxi.yxregiserve.web.grpc.impl;
import com.yanxi.yxregiserve.web.grpc.messService.MessRequest;
import com.yanxi.yxregiserve.web.grpc.messService.MessResponse;
import com.yanxi.yxregiserve.web.grpc.messService.MessServiceGrpc;
import net.devh.boot.grpc.server.service.GrpcService;
@GrpcService
public class MessServiceImpl extends MessServiceGrpc.MessServiceImplBase {
@Override
public void getHello(MessRequest request, io.grpc.stub.StreamObserver<MessResponse> responseStreamObserver) {
System.out.println(request.getStr());
responseStreamObserver.onNext(MessResponse.newBuilder()
.setData("返回的数据")
.setStatus(200)
.setMsg("操作成功")
.build());
responseStreamObserver.onCompleted();
}
}
OK 客户端就配置完毕了!
服务端
1、Maven配置
<!-- grpc 连接客户端-->
<dependency>
<groupId>net.devh</groupId>
<artifactId>grpc-client-spring-boot-starter</artifactId>
</dependency>
<!-- grpc 自身服务-->
<dependency>
<groupId>net.devh</groupId>
<artifactId>grpc-server-spring-boot-starter</artifactId>
</dependency>
2、application.yml配置
grpc:
server:
port: 8091
client:
yx-regiserve:
address: static://localhost:8090
enableKeepAlive: true
keepAliveWithoutCalls: true
negotiationType: plaintext
3、proto 文件
创建一个 mess.proto 文件放在 src/main/proto 目录下
// proto 文件放在 src/main/proto 目录下
// 指定使用 proto3 语法
syntax = "proto3";
// 生成的 Java 代码将被拆分为多个文件
option java_multiple_files = true;
// 指定生成的 Java 代码所在的包
option java_package = "com.yanxi.yxregiserve.web.grpc.messService";
// 定义一个 gRPC 服务,名为 MessService
service MessService {
// 定义一个 gRPC 方法,名为 getHello
// 接收一个 MessRequest 参数,并返回一个 MessResponse
rpc getHello(MessRequest) returns (MessResponse) {}
}
// 定义一个接受消息类型,名为 MessRequest
message MessRequest{
string str = 1;
}
// 定义一个返回消息类型,名为 MessResponse
message MessResponse {
// 状态
int32 status = 1;
// 消息
string msg = 2;
// 数据
string data = 3;
}
4、编译
mvn compile
或者
因为子啊proto文件中配置了,所以
编译完成就会在你的 src\main\java\com\yanxi\yxregiserve\web\grpc\messService目录中出现:
这就是反编译的java代码。
3、4步骤 这么写有感觉一点冗余,但是目前我是这么实现的,让我以后琢磨琢磨怎么用更好的方法实现,以后更新。
5、调用客户端
@SpringBootTest
class YxModel1ApplicationTests {
@GrpcClient("yx-regiserve")
private MessServiceGrpc.MessServiceBlockingStub messServiceBlockingStub;
@Test
void contextLoads() {
MessResponse response = messServiceBlockingStub.getHello(MessRequest.newBuilder()
.setStr("你好呀")
.build());
// 处理返回结果
System.out.println(response.getData());
System.out.println(response.getStatus());
System.out.println(response.getMsg());
}
}
调试结果
1、启动客户端
2、启动服务端 测试类
服务端发送的请求值
完活
YanXi 项目
是我在写了这篇博客之后,决定要手把手的把这玩意实现~
然后便有了这个开源项目 ,小菜鸡一个,各位大佬轻点…我感觉还是要勇于尝试,勇于试错,虽然不难,但是也是我的一个小小的心血吧~
YanXi 开源项目地址: