手把手教你写一个SpringBoot+gRPC服务
作者:酸奶小肥阳
请注意,本文不会对gRPC基础概念进行解释,而是着重介绍服务的搭建过程。如果你是零基础的伙伴,请先自行学习gRPC的基础知识。接下来,让我们在本地环境下搭建gRPC客户端和服务端,并成功建立通讯发送消息的方式,来学习gRPC在Spring Boot项目中的应用。
客户端(发送rpc请求)
1、导入maven依赖
包含rpc所使用的依赖和构建protobuf的插件。完整的<dependencies>
和<build>
如下:
<dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-test</artifactId> <scope>test</scope> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <dependency> <groupId>io.grpc</groupId> <artifactId>grpc-netty-shaded</artifactId> <version>1.59.1</version> <scope>runtime</scope> </dependency> <dependency> <groupId>io.grpc</groupId> <artifactId>grpc-protobuf</artifactId> <version>1.59.1</version> </dependency> <dependency> <groupId>io.grpc</groupId> <artifactId>grpc-stub</artifactId> <version>1.59.1</version> </dependency> <dependency> <!-- necessary for Java 9+ --> <groupId>org.apache.tomcat</groupId> <artifactId>annotations-api</artifactId> <version>6.0.53</version> <scope>provided</scope> </dependency> </dependencies> <build> <extensions> <extension> <groupId>kr.motd.maven</groupId> <artifactId>os-maven-plugin</artifactId> <version>1.7.1</version> </extension> </extensions> <plugins> <plugin> <groupId>org.xolstice.maven.plugins</groupId> <artifactId>protobuf-maven-plugin</artifactId> <version>0.6.1</version> <configuration> <protocArtifact>com.google.protobuf:protoc:3.24.0:exe:${os.detected.classifier}</protocArtifact> <pluginId>grpc-java</pluginId> <pluginArtifact>io.grpc:protoc-gen-grpc-java:1.59.1:exe:${os.detected.classifier}</pluginArtifact> </configuration> <executions> <execution> <goals> <goal>compile</goal> <goal>compile-custom</goal> </goals> </execution> </executions> </plugin> </plugins> </build>
导入成功后,可以在maven的插件中看到protobuf选项;
2、编写Proto文件
在main目录下创建proto软件包,将编写好的Proto文件放在该目录(src/main/proto
)下。示例Proto文件内容如下
syntax = "proto3"; option java_multiple_files = true; option java_package = "com.example.server"; option java_outer_classname = "HelloWorldProto"; option objc_class_prefix = "HLW"; package com.example.server; service Greeter { rpc SayHello (HelloRequest) returns (HelloReply) {} } message HelloRequest { string name = 1; } message HelloReply { string message = 1; }
完成Proto文件编写后,执行mvn install
命令。你会在target/generated-sources/protobuf
路径下看到gRPC编译生成的Java代码。这些生成的代码是实现gRPC在不同语言间进行RPC通讯的基础。
3、编写客户端代码
创建一个HelloWorldClient类,实例化stub
对象,并发送rpc请求的方法;
@Service public class HelloWorldClient { private GreeterGrpc.GreeterBlockingStub stub; @Value("${grpc.hello-world.host}") private String host; @Value("${grpc.hello-world.port}") private Integer port; @PostConstruct void init() { ManagedChannel channel = ManagedChannelBuilder.forAddress(host, port) .keepAliveWithoutCalls(true) .keepAliveTime(60, TimeUnit.SECONDS) .keepAliveTimeout(3, TimeUnit.SECONDS) .idleTimeout(60, TimeUnit.SECONDS) .maxInboundMessageSize(Integer.MAX_VALUE) .usePlaintext().build(); stub = GreeterGrpc.newBlockingStub(channel); } /** * 说“你好” * * @param name 名字 * @return {@link String} */ public String sayHello(String name) { HelloRequest request = HelloRequest.newBuilder().setName(name).build(); HelloReply helloReply = stub.sayHello(request); return helloReply.getMessage(); } }
这里我配置的gRPC服务端地址如下,请根据实际情况修改host和port的值。
grpc: hello-world: host: 127.0.0.1 port: 6565
接下来,让我们继续开发服务端的代码。
服务端(处理rpc请求并返回处理数据)
1、导入maven依赖
与客户端依赖略有不同,服务端中我们使用了grpc-spring-boot-starter
<dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-test</artifactId> <scope>test</scope> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <dependency> <groupId>io.grpc</groupId> <artifactId>grpc-protobuf</artifactId> <version>1.53.0</version> </dependency> <dependency> <groupId>io.grpc</groupId> <artifactId>grpc-stub</artifactId> <version>1.53.0</version> </dependency> <dependency> <groupId>org.projectlombok</groupId> <artifactId>lombok</artifactId> </dependency> <dependency> <groupId>org.lognet</groupId> <artifactId>grpc-spring-boot-starter</artifactId> <version>2.3.2</version> </dependency> </dependencies> <!-- 添加protobuf-maven-plugin插件 编译proto文件--> <build> <extensions> <extension> <groupId>kr.motd.maven</groupId> <artifactId>os-maven-plugin</artifactId> <version>1.6.2</version> </extension> </extensions> <plugins> <plugin> <groupId>org.xolstice.maven.plugins</groupId> <artifactId>protobuf-maven-plugin</artifactId> <version>0.6.1</version> <configuration> <protocArtifact>com.google.protobuf:protoc:3.17.3:exe:${os.detected.classifier}</protocArtifact> <pluginId>grpc-java</pluginId> <pluginArtifact>io.grpc:protoc-gen-grpc-java:1.42.0:exe:${os.detected.classifier}</pluginArtifact> </configuration> <executions> <execution> <goals> <goal>compile</goal> <goal>compile-custom</goal> </goals> </execution> </executions> </plugin> </plugins> </build> </project>
2、导入Proto文件
这里的proto文件尽量和客户端的保持一致,完成和客户端步骤2同样的事儿。需要注意的是,在proto文件中,用package
声明生成的Java类的包名,请与服务端实现类的包结构保持一致,这样才能正常地完成依赖导入和方法重写;
例如:
3、编写服务端实现类代码
@GRpcService
:用于标记这个类是一个gRPC服务端的实现类。它告诉Spring Boot框架将这个类注册为一个gRPC服务端,并自动处理gRPC请求。- 继承自
GreeterGrpc.GreeterImplBase
类,表示它是rpc服务Greeter
的实现类,在类中,我们可以重写rpc接口的实现方法,来处理接收到请求;
/** * hello service impl * * @author yangyang * @date 2023/11/30 */ @GRpcService @Slf4j public class HelloServiceImpl extends GreeterGrpc.GreeterImplBase { @Override public void sayHello(HelloRequest request, StreamObserver<HelloReply> responseObserver) { // 获取客户端发送的请求消息 String name = request.getName(); // 构建响应消息 HelloReply response = HelloReply.newBuilder() .setMessage("Hello, " + name + "!") .build(); log.info("[grpc server]: response: {}", response); // 发送响应消息 responseObserver.onNext(response); // 通知客户端响应已经完成 responseObserver.onCompleted(); } }
4、配置端口号,启动服务
可通过此配置修改rpc的端口号(默认6565)
grpc: # grpc server port port: 6565 server: port: 8081
服务启动后,可以在日志中看到端口信息
可以选择使用通过客户端发送请求来测试服务,或者使用postman等工具发送rpc接口。至此,一个简单且完整的SpringBoot gRPC客户端与服务端开发完成!
以上就是手把手教你写一个SpringBoot+gRPC服务的详细内容,更多关于SpringBoot gRPC服务的资料请关注脚本之家其它相关文章!