gRPC了解并与spring boot集成demo
一、简介
gRPC 是一个高性能、开源和通用的 RPC 框架,面向移动和 HTTP/2 设计。目前提供 C、Java 和 Go 语言版本,分别是:grpc, grpc-java, grpc-go. 其中 C 版本支持 C, C++, Node.js, Python, Ruby, Objective-C, PHP 和 C# 支持.
gRPC 基于 HTTP/2 标准设计,带来诸如双向流、流控、头部压缩、单 TCP 连接上的多复用请求等特。这些特性使得其在移动设备上表现更好,更省电和节省空间占用。
二、概览
在 gRPC 里客户端应用可以像调用本地对象一样直接调用另一台不同的机器上服务端应用的方法,使得您能够更容易地创建分布式应用和服务。与许多 RPC 系统类似,gRPC 也是基于以下理念:定义一个服务,指定其能够被远程调用的方法(包含参数和返回类型)。在服务端实现这个接口,并运行一个 gRPC 服务器来处理客户端调用。在客户端拥有一个存根能够像服务端一样的方法。
gRPC 客户端和服务端可以在多种环境中运行和交互 - 从 google 内部的服务器到你自己的笔记本,并且可以用任何 gRPC
[支持的语言]
来编写。所以,你可以很容易地用 Java 创建一个 gRPC 服务端,用 Go、Python、Ruby 来创建客户端。此外,Google 最新 API 将有 gRPC 版本的接口,使你很容易地将 Google 的功能集成到你的应用里。
三、使用 protocol buffers
gRPC 默认使用 protocol buffers*,这是 Google 开源的一套成熟的结构数据序列化机制(当然也可以使用其他数据格式如 JSON)。正如你将在下方例子里所看到的,你用 *proto files 创建 gRPC 服务,用 protocol buffers 消息类型来定义方法参数和返回类型。关于protocol buffers你可以参考[https://www.jarvanbest.com/2021/05/25/Protocol-Buffers%E4%BD%BF%E7%94%A8%E6%8C%87%E5%8D%97/或在官方文档了解。](https://www.jarvanbest.com/2021/05/25/Protocol-Buffers使用指南/**或在官方文档了解。)
四、使用spring boot集成grpc
1、创建spring boot项目
勾选springboot-web和lombok即可,然后增加grpc的starter
<dependency>
<groupId>io.github.lognet</groupId>
<artifactId>grpc-spring-boot-starter</artifactId>
<version>3.4.1</version>
</dependency>
配置build脚本
<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.5.1</version>
<configuration>
<protocArtifact>com.google.protobuf:protoc:3.6.1:exe:${os.detected.classifier}</protocArtifact>
<pluginId>grpc-java</pluginId>
<pluginArtifact>io.grpc:protoc-gen-grpc-java:1.19.0:exe:${os.detected.classifier}</pluginArtifact>
</configuration>
<executions>
<execution>
<goals>
<goal>compile</goal>
<goal>compile-custom</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
简单依赖如下
<properties>
<java.version>1.8</java.version>
<io.grpc.version>1.23.0</io.grpc.version>
<os-maven-plugin.version>1.5.0.Final</os-maven-plugin.version>
<protobuf-maven-plugin.version>0.5.1</protobuf-maven-plugin.version>
<grpc-starter-version>3.4.1</grpc-starter-version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>io.github.lognet</groupId>
<artifactId>grpc-spring-boot-starter</artifactId>
<version>3.4.1</version>
</dependency>
</dependencies>
2、编写proto文件
在java同级目录建立proto文件夹
然后编写如下三个proto文件
syntax = "proto3";
option java_multiple_files = true;
package com.jarvan.grpcdemo.grpc;
message Member {
string username = 1;
string password = 2;
string info = 3;
}
列表rpc服务
syntax = "proto3";
option java_multiple_files = true;
package com.jarvan.grpcdemo.grpc;
import "Member.proto";
message MemberListRequest {
int32 page = 1;
int32 per_page = 2;
}
message MemberListResponse {
repeated Member member = 1;
}
service MemberListService {
rpc member_list(MemberListRequest) returns (MemberListResponse);
}
登录rpc服务
syntax = "proto3";
option java_multiple_files = true;
package com.jarvan.grpcdemo.grpc;
import "Member.proto";
message MemberLoginRequest {
Member member = 1;
}
message MemberLoginResponse {
string token = 1;
}
service MemberLoginService {
rpc member_login(MemberLoginRequest) returns (MemberLoginResponse);
}
3、IDEA安装插件并生成代码
Protocol Buffer Editor `或者 `Protobuf Support
安装成功后maven插件中找到下述并编译
编译后会在target生成相关代码
4、代码
创建相关bean并注入spring
@Configuration
public class GrpcConfig {
@Bean
ManagedChannel channel(@Value("${app-config.grpc-server-name}") String name,
@Value("${app-config.grpc-server-port}") Integer port) {
return ManagedChannelBuilder.forAddress(name, port).usePlaintext().build();
}
@Bean
MemberListServiceGrpc.MemberListServiceBlockingStub memberListServiceBlockingStub(ManagedChannel channel) {
return MemberListServiceGrpc.newBlockingStub(channel);
}
@Bean
MemberLoginServiceGrpc.MemberLoginServiceBlockingStub memberLoginServiceBlockingStub(ManagedChannel channel) {
return MemberLoginServiceGrpc.newBlockingStub(channel);
}
}
创建列表服务和登录服务
@GRpcService
public class MemberListServiceImpl extends MemberListServiceGrpc.MemberListServiceImplBase {
@Override
public void memberList(MemberListRequest request, StreamObserver<MemberListResponse> responseObserver) {
Member jarvan = Member.newBuilder()
.setPassword("123456")
.setUsername("jarvan")
.setInfo("hello jarvan")
.build();
Member hello = Member.newBuilder()
.setPassword("123456")
.setUsername("hello")
.setInfo("hello world")
.build();
MemberListResponse.Builder builder = MemberListResponse.newBuilder();
builder.addMember(jarvan);
builder.addMember(hello);
MemberListResponse response = builder.build();
responseObserver.onNext(response);
responseObserver.onCompleted();
}
}
@GRpcService
public class MemberLoginServiceImpl extends MemberLoginServiceGrpc.MemberLoginServiceImplBase {
@Override
public void memberLogin(MemberLoginRequest request, StreamObserver<MemberLoginResponse> responseObserver) {
String token = "";
if("123456".equals(request.getMember().getPassword())){
token = "success";
}
MemberLoginResponse response = MemberLoginResponse
.newBuilder()
.setToken(token)
.build();
responseObserver.onNext(response);
responseObserver.onCompleted();
}
}
5、测试
curl "http://localhost:8080/list"
curl -X POST http://localhost:8080/login -H "Content-type: application/json" -d "{\"username\":\"jarvan\", \"password\":\"123456\"}"
使用curl或者postman进行测试,成功后结果如下
项目整体目录结构如下
五、源码
代码已上传github
https://github.com/JarvanBest/spring-boot-grpc https://github.com/JarvanBest/grpc-official-demo