网站首页 > 文章精选 正文
在分布式系统架构中,高效的服务间通信至关重要。gRPC 作为一款现代化的开源高性能远程过程调用(RPC)框架,凭借其跨环境运行能力、可插拔的负载均衡、追踪、健康检查和认证支持等特性,成为连接服务的理想选择。而 Spring 官方对 gRPC 的支持,更是让开发者在 Spring 生态中集成 gRPC 变得简单高效,本文就带你通过实战案例,快速掌握 Spring Boot 环境下 gRPC 的应用。
一、gRPC 与 Spring gRPC 初探
gRPC 能高效连接数据中心内部及跨数据中心的服务,也适用于分布式计算的 “最后一公里”,连接设备、移动应用、浏览器与后端服务。
Spring gRPC 项目为 gRPC 应用开发提供了与 Spring 生态兼容的 API 和抽象层,其核心库让 gRPC 中依赖注入的使用变得轻松,Spring Boot 启动器更是简化了在 Spring Boot 应用中开启 gRPC 的流程。
二、实战:Spring Boot 集成 gRPC
(一)环境准备
本次实战基于 Spring Boot 3.4.2 版本,需准备好相应的开发环境,如 JDK、Maven 等。
(二)依赖配置
要使用 gRPC,首先需引入必要的依赖并进行 build 配置,以通过 proto 文件生成 java 文件。
- 核心依赖
xml
<dependency>
<groupId>io.grpc</groupId>
<artifactId>grpc-services</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.grpc</groupId>
<artifactId>spring-grpc-server-web-spring-boot-starter</artifactId>
</dependency>
- build 配置
xml
<build>
<extensions>
<extension>
<groupId>kr.motd.maven</groupId>
<artifactId>os-maven-plugin</artifactId>
<version>1.7.1</version>
</extension>
</extensions>
<plugins>
<plugin>
<groupId>org.graalvm.buildtools</groupId>
<artifactId>native-maven-plugin</artifactId>
<configuration>
<buildArgs>
<buildArg>--verbose</buildArg>
</buildArgs>
</configuration>
</plugin>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-deploy-plugin</artifactId>
<configuration>
<skip>true</skip>
</configuration>
</plugin>
<plugin>
<groupId>io.spring.javaformat</groupId>
<artifactId>spring-javaformat-maven-plugin</artifactId>
<version>${spring-javaformat-maven-plugin.version}</version>
<executions>
<execution>
<?m2e ignore?>
<phase>validate</phase>
<inherited>true</inherited>
<goals>
<goal>validate</goal>
</goals>
</execution>
</executions>
</plugin>
<plugin>
<groupId>io.github.ascopes</groupId>
<artifactId>protobuf-maven-plugin</artifactId>
<version>3.1.2</version>
<configuration>
<protocVersion>${protobuf-java.version}</protocVersion>
<binaryMavenPlugins>
<binaryMavenPlugin>
<groupId>io.grpc</groupId>
<artifactId>protoc-gen-grpc-java</artifactId>
<version>${grpc.version}</version>
<classifier>${os.detected.classifier}</classifier>
<options>jakarta_omit,@generated=omit</options>
</binaryMavenPlugin>
</binaryMavenPlugins>
<outputDirectory>src/main/java</outputDirectory>
</configuration>
<executions>
<execution>
<?m2e execute onConfiguration,onIncremental?>
<goals>
<goal>generate</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
(三)编写 proto 文件
在 src/main/protobuf 目录下新建 hello.proto 文件,用于定义服务和消息类型:
protobuf
syntax = "proto3";
option java_multiple_files = true;
option java_package = "com.pack.grpc.proto";
option java_outer_classname = "HelloWorldProto";
// 定义服务
service Simple {
// 发送消息
rpc SayHello(HelloRequest) returns (HelloReply) {}
rpc StreamHello(HelloRequest) returns (stream HelloReply) {}
}
// 请求消息
message HelloRequest {
string name = 1;
}
// 响应消息
message HelloReply {
string message = 1;
}
(四)生成 Java 文件
在项目根目录执行mvnw clean package命令,生成的 Java 文件会保存到 src/main/java 下的 com.pack.grpc.proto 包中,包括 HelloReply.java、HelloRequest.java、SimpleGrpc.java 等,这些文件是后续实现服务和客户端的基础。
(五)实现 gRPC 服务端
创建 GrpcServerService 类,继承 SimpleGrpc.SimpleImplBase,重写服务方法:
java
@Service
public class GrpcServerService extends SimpleGrpc.SimpleImplBase {
private static Logger log = LoggerFactory.getLogger(GrpcServerService.class);
@Override
public void sayHello(HelloRequest req, StreamObserver<HelloReply> responseObserver) {
log.info("Hello, {}", req.getName());
if (req.getName().startsWith("error")) {
throw new IllegalArgumentException("Bad name: " + req.getName());
}
if (req.getName().startsWith("internal")) {
throw new RuntimeException();
}
HelloReply reply = HelloReply.newBuilder().setMessage("Hello ==> " + req.getName()).build();
responseObserver.onNext(reply);
responseObserver.onCompleted();
}
@Override
public void streamHello(HelloRequest req, StreamObserver<HelloReply> responseObserver) {
log.info("Hello, {}", req.getName());
int count = 0;
while (count < 10) {
HelloReply reply = HelloReply.newBuilder().setMessage("Hello(" + count + ") ==> " + req.getName()).build();
responseObserver.onNext(reply);
count++;
try {
Thread.sleep(1000L);
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
responseObserver.onError(e);
return;
}
}
responseObserver.onCompleted();
}
}
同时,在配置文件中设置服务端地址信息:
yaml
spring:
grpc:
server:
host: 0.0.0.0
port: 9090
ssl:
secure: false
enabled: false
servlet:
enabled: false
启动服务后,日志会显示 gRPC 服务已启动,监听在 9090 端口。
(六)实现 gRPC 客户端
- 配置客户端:创建 GRpcConfig 配置类,定义 SimpleGrpc.SimpleBlockingStub 的 bean:
java
@Configuration
public class GRpcConfig {
@Bean
SimpleGrpc.SimpleBlockingStub stub(GrpcChannelFactory channels) {
// 也可以通过命名通道方式
return SimpleGrpc.newBlockingStub(channels.createChannel("local"));
}
}
- 客户端配置文件:
yaml
spring:
grpc:
client:
default-channel:
secure: false
ssl:
enabled: false
channels:
local:
address: 0.0.0.0:9090
(七)测试 gRPC 调用
创建 GrpcController 类,注入
SimpleGrpc.SimpleBlockingStub,通过接口测试调用:
java
@RestController
@RequestMapping("/grpc")
public class GrpcController {
private final SimpleGrpc.SimpleBlockingStub stub;
public GrpcController(SimpleBlockingStub stub) {
this.stub = stub;
}
@GetMapping("/invoke")
public ResponseEntity<?> invoke(String message) throws Exception {
HelloRequest request = HelloRequest.newBuilder()
.setName(message)
.build();
return ResponseEntity.ok(stub.sayHello(request).getMessage());
}
}
启动客户端后,访问
localhost:8080/grpc/invoke?message=Pack,会得到Hello ==> Pack的响应,表明 gRPC 调用成功。
通过以上实战步骤,我们清晰地看到在 Spring Boot 环境下集成 gRPC 的便捷性。借助 Spring 官方的支持,开发者无需复杂配置,就能快速实现高性能的 RPC 通信,极大地提升了分布式系统中服务间交互的效率。如果你正在构建分布式应用,不妨尝试一下 gRPC,体验其带来的高性能与便捷性。
感谢关注【AI码力】,获取更多Java秘籍!
猜你喜欢
- 2025-08-01 go-zero 实践 - 编写仓储、订单RPC\API服务(五)
- 2025-08-01 PS3安卓模拟器“换马甲”重生:RPCSX-UI-Android上线
- 2025-08-01 大数据技术大合集:Hadoop、Cloudera...
- 2025-08-01 项目经验分享
- 2025-08-01 腾讯开源框架TarsCpp-rpc设计分析-client(一)
- 2025-08-01 什么是RPC?什么是Restful?它们有什么区别?
- 2025-08-01 日产2000片!南方路机助力中山东环RPC项目实现“超级智造”投产
- 2025-08-01 教你用 Netty 实现一个简单的 RPC
- 2025-08-01 6种微服务RPC框架,你知道几个?
- 2025-08-01 java 服务之间调用(rpc)
- 最近发表
- 标签列表
-
- newcoder (56)
- 字符串的长度是指 (45)
- drawcontours()参数说明 (60)
- unsignedshortint (59)
- postman并发请求 (47)
- python列表删除 (50)
- 左程云什么水平 (56)
- 编程题 (64)
- postgresql默认端口 (66)
- 数据库的概念模型独立于 (48)
- 产生系统死锁的原因可能是由于 (51)
- 数据库中只存放视图的 (62)
- 在vi中退出不保存的命令是 (53)
- 哪个命令可以将普通用户转换成超级用户 (49)
- noscript标签的作用 (48)
- 联合利华网申 (49)
- swagger和postman (46)
- 结构化程序设计主要强调 (53)
- 172.1 (57)
- apipostwebsocket (47)
- 唯品会后台 (61)
- 简历助手 (56)
- offshow (61)
- mysql数据库面试题 (57)
- fmt.println (52)