一、gRPC概念介绍
gRPC(Google Remote Procedure Call,Google远程过程调用)是一个现代开源高性能远程过程调用(RPC)框架,可以在任何环境中运行。它由Google开发,旨在帮助开发人员更轻松地构建分布式应用,特别是当代码可能在不同地方运行的时候。
gRPC是一个高性能、开源和通用的RPC框架,它基于HTTP/2设计,并支持多种编程语言和平台。
随着其开源和广泛应用,gRPC已成为云原生计算基金会(CNCF)的一个孵化项目,被大量组织和企业采用。
核心特点
- 高性能:gRPC使用HTTP/2作为传输协议,支持二进制组帧、多路复用、双向全双工通信和流式处理等功能,从而显著提高性能。与JSON相比,gRPC的消息序列化速度更快,消息体积更小。
- 跨平台与跨语言:gRPC支持多种编程语言和平台,如C++、Java、Python、Go等,使得开发人员可以在不同的环境中使用统一的RPC框架。
- 灵活性与可扩展性:gRPC提供了丰富的功能,如负载平衡、跟踪、健康检查和身份验证等,这些功能都是可插拔的,可以根据需要进行配置和扩展。
- 安全性:gRPC支持TLS加密,确保数据在传输过程中的安全性。同时,它还支持多种认证机制,如JWT(JSON Web Tokens)等,以确保服务的访问安全。
工作原理
- 服务定义:在gRPC中,服务通过.proto文件进行定义。这些文件包含了服务的接口描述、消息类型等信息。开发人员可以使用Protocol Buffers(简称Protobuf)来定义这些结构化的消息。
- 代码生成:基于.proto文件,gRPC提供了protoc编译器来生成支持多种编程语言的客户端和服务端代码。这使得开发人员可以轻松地实现跨语言的RPC调用。
- 通信过程:在客户端和服务端之间,gRPC通过HTTP/2协议进行通信。客户端发送请求到服务端,服务端处理请求并返回响应。整个通信过程都是基于二进制格式的,从而提高了性能和效率。
应用场景
- 微服务架构:在微服务架构中,gRPC可以有效地连接多语言服务,实现服务间的快速通信。
- 分布式计算:gRPC适用于分布式计算的最后一英里,将设备、移动应用程序和浏览器连接到后端服务。
- API设计:与REST API相比,gRPC提供了一种更加高效和灵活的API设计风格,适用于需要高性能和低延迟的应用场景。
二、简单使用步骤
首先,你需要定义gRPC服务。这里我们使用一个简单的helloworld.proto
文件。
1. helloworld.proto
syntax = "proto3";
option java_multiple_files = true;
option java_package = "com.example.grpc";
option java_outer_classname = "HelloWorldProto";
package helloworld;
service HelloWorldService {
rpc SayHello (HelloRequest) returns (HelloReply) {}
}
message HelloRequest {
string name = 1;
}
message HelloReply {
string message = 1;
}
2. 生成Java代码
使用protoc编译器和gRPC插件生成Java代码。
protoc --java_out=./src/main/java --grpc-java_out=./src/main/java --plugin=protoc-gen-grpc-java=/path/to/protoc-gen-grpc-java-1.x.x-linux-x86_64.exe helloworld.proto
确保将/path/to/protoc-gen-grpc-java-1.x.x-linux-x86_64.exe
替换为你的protoc-gen-grpc-java
插件的实际路径。
3. 服务端实现
在Spring Boot应用中,你可以创建一个组件来实现gRPC服务。
package com.example.grpc;
import io.grpc.stub.StreamObserver;
import net.devh.boot.grpc.server.service.GrpcService;
@GrpcService
public class HelloWorldServiceImpl extends HelloWorldServiceGrpc.HelloWorldServiceImplBase {
@Override
public void sayHello(HelloRequest req, StreamObserver<HelloReply> responseObserver) {
String message = "Hello, " + req.getName() + "!";
HelloReply reply = HelloReply.newBuilder().setMessage(message).build();
responseObserver.onNext(reply);
responseObserver.onCompleted();
}
}
4. 客户端调用
在Spring Boot应用中,你可以创建一个服务来调用gRPC服务。这里使用JUnit单元测试
import com.example.grpc.HelloReply;
import com.example.grpc.HelloRequest;
import com.example.grpc.HelloWorldServiceGrpc;
import io.grpc.ManagedChannel;
import io.grpc.ManagedChannelBuilder;
import org.junit.jupiter.api.Test;
public class HelloWorldClientServiceTest {
@Test
public void sayHello() {
ManagedChannel channel = ManagedChannelBuilder.forTarget("localhost:9091").usePlaintext().build();
HelloWorldServiceGrpc.HelloWorldServiceBlockingStub stub = HelloWorldServiceGrpc.newBlockingStub(channel);
HelloReply response = stub.sayHello(HelloRequest.newBuilder().setName("Lisa").build());
System.out.println("response = " + response);
channel.shutdown();
}
}
5. 构建和运行
确保你的pom.xml
中包含了必要的gRPC和Spring Boot依赖。
然后执行maven compile
指令生成java代码
mvn compile
启动SpringBoot服务端,然后运行测试用例,得到如下结果:
response = message: "Hello, Lisa!"
三、添加gRPC相关依赖包
参考 grpc-spring
在Spring Boot项目中使用gRPC,你需要在项目的pom.xml
中添加相关的gRPC依赖。
以下是在Maven项目中添加gRPC依赖的示例。
<dependencies>
<dependency>
<groupId>com.salesforce.servicelibs</groupId>
<artifactId>jprotoc</artifactId>
<version>1.2.2</version>
</dependency>
<dependency>
<groupId>net.devh</groupId>
<artifactId>grpc-spring-boot-starter</artifactId>
<version>${grpc-spring-boot-starter.version}</version>
</dependency>
</dependencies>
<properties>
<protobuf-maven-plugin.version>0.6.1</protobuf-maven-plugin.version>
<protoc.version>3.25.1</protoc.version>
<grpc-java.version>1.64.0</grpc-java.version>
<os-maven-plugin.version>1.7.1</os-maven-plugin.version>
</properties>
请注意,你需要将${grpc-java.version}
、${grpc-spring-boot-starter.version}
替换为你想要使用的具体版本号。
这些依赖项包括了gRPC的基础库、与Protobuf的集成、以及Spring Boot对gRPC的支持。确保你使用的版本是兼容的,并根据你的项目需求进行调整。如果你还需要使用到其他的gRPC功能(如安全认证、健康检查等),你可能需要添加更多的依赖项。
四、使用Maven插件自动生成proto对应代码
参考 os-maven-plugin 和 protobuf-maven-plugin
如果你希望通过maven编译时自动生成proto对应的java代码,则需要添加Maven插件和相关依赖
<properties>
<protobuf-maven-plugin.version>0.6.1</protobuf-maven-plugin.version>
<protoc.version>3.25.1</protoc.version>
<grpc-java.version>1.64.0</grpc-java.version>
<os-maven-plugin.version>1.7.1</os-maven-plugin.version>
<grpc-spring-boot-starter.version>3.1.0.RELEASE</grpc-spring-boot-starter.version>
</properties>
//...//
<dependencies>
<dependency>
<groupId>com.salesforce.servicelibs</groupId>
<artifactId>jprotoc</artifactId>
<version>1.2.2</version>
</dependency>
<!-- gRPC Server + Client -->
<dependency>
<groupId>net.devh</groupId>
<artifactId>grpc-spring-boot-starter</artifactId>
<version>${grpc-spring-boot-starter.version}</version>
</dependency>
</dependencies>
// ... //
<build>
<extensions>
<extension>
<groupId>kr.motd.maven</groupId>
<artifactId>os-maven-plugin</artifactId>
<version>${os-maven-plugin.version}</version>
</extension>
</extensions>
<pluginManagement>
<plugins>
<!-- protobuf-maven-plugin -->
<plugin>
<groupId>org.xolstice.maven.plugins</groupId>
<artifactId>protobuf-maven-plugin</artifactId>
<version>${protobuf-maven-plugin.version}</version>
<extensions>true</extensions>
<executions>
<execution>
<id>protoc-compile</id>
<phase>generate-sources</phase>
<goals>
<goal>compile</goal>
<goal>compile-custom</goal>
</goals>
</execution>
<execution>
<id>protoc-test-compile</id>
<phase>generate-test-sources</phase>
<goals>
<goal>test-compile</goal>
<goal>test-compile-custom</goal>
</goals>
</execution>
</executions>
<configuration>
<protocArtifact>
com.google.protobuf:protoc:${protoc.version}:exe:${os.detected.classifier}
</protocArtifact>
<attachProtoSources>true</attachProtoSources>
<useArgumentFile>true</useArgumentFile>
<writeDescriptorSet>false</writeDescriptorSet>
<attachDescriptorSet>false</attachDescriptorSet>
<includeDependenciesInDescriptorSet>false</includeDependenciesInDescriptorSet>
<checkStaleness>true</checkStaleness>
<pluginId>grpc-java</pluginId>
<pluginArtifact>
io.grpc:protoc-gen-grpc-java:${grpc.version}:exe:${os.detected.classifier}
</pluginArtifact>
<protocPlugins>
</protocPlugins>
</configuration>
</plugin>
</plugins>
</pluginManagement>
<plugins>
<plugin>
<groupId>org.xolstice.maven.plugins</groupId>
<artifactId>protobuf-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
通过上面配置后,你就可以在项目中通过指令mvn compile
生成proto对应的java代码,不需要通过外包指令了。
参考
- https://protobuf.com.cn/overview/
- https://protobuf.dev/getting-started/javatutorial/
- https://protobuf.dev/reference/java/java-generated/
- https://protobuf.dev/programming-guides/proto3/
- https://github.com/grpc-ecosystem/grpc-spring
- https://www.xolstice.org/protobuf-maven-plugin/
- https://github.com/trustin/os-maven-plugin/