文章目录
- 一、SpringBoot 使用 grpc 实现远程服务调用
- 1、服务端编写
- 2、客户端编写
一、SpringBoot 使用 grpc 实现远程服务调用
gRPC 是一个现代的、开源的、高性能的远程过程调用(RPC)框架,可以在任何地方运行。gRPC 使客户端和服务器应用程序能够透明地通信,并简化了连接系统的构建。
为了最大限度地提高可用性,gRPC 支持向用户选择的语言(如果有)添加依赖项的标准方法。在大多数语言中,gRPC 运行时作为用户语言包管理器中可用的包提供。
核心依赖之间的关系:
- grpc-spring-boot-starter:包含了客户端和服务端
- grpc-server-spring-boot-starter:只有服务端
- grpc-client-spring-boot-starter:只有客户端
1、服务端编写
通常情况下,服务端也会是客户端,所以这里引用依赖直接客户端、服务端一起引入
<properties>
<java.version>1.8</java.version>
<grpc-spring-boot-starter.version>2.14.0.RELEASE</grpc-spring-boot-starter.version>
<os-maven-plugin.version>1.6.0</os-maven-plugin.version>
<protobuf-maven-plugin.version>0.5.1</protobuf-maven-plugin.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>net.devh</groupId>
<artifactId>grpc-spring-boot-starter</artifactId>
<version>${grpc-spring-boot-starter.version}</version>
</dependency>
</dependencies>
<build>
<extensions>
<!-- os-maven-plugin -->
<extension>
<groupId>kr.motd.maven</groupId>
<artifactId>os-maven-plugin</artifactId>
<version>${os-maven-plugin.version}</version>
</extension>
</extensions>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<executions>
<execution>
<goals>
<goal>repackage</goal>
</goals>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<configuration>
<skip>true</skip>
</configuration>
</plugin>
<!-- protobuf-maven-plugin -->
<plugin>
<groupId>org.xolstice.maven.plugins</groupId>
<artifactId>protobuf-maven-plugin</artifactId>
<version>${protobuf-maven-plugin.version}</version>
<configuration>
<protocArtifact>com.google.protobuf:protoc:3.5.1-1:exe:${os.detected.classifier}</protocArtifact>
<pluginId>grpc-java</pluginId>
<pluginArtifact>io.grpc:protoc-gen-grpc-java:1.11.0:exe:${os.detected.classifier}</pluginArtifact>
<outputDirectory>${project.build.sourceDirectory}</outputDirectory>
<clearOutputDirectory>false</clearOutputDirectory>
</configuration>
<executions>
<execution>
<goals>
<goal>compile</goal>
<goal>compile-custom</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
然后在创建 src/main/proto 文件夹,并在其中创建 news.proto 文件
syntax = "proto3";
option java_package = "cn.tellsea.grpcservice.proto";
service NewsService {
rpc Hello (StringRequest) returns (StringResponse) {}
}
message StringRequest {
string name = 1;
}
message StringResponse {
string result = 1;
}
然后在 maven 中执行生成代码
执行完成之后,会直接生成可调用的代码
然后编写自己的业务 Service 方法,注意使用@GrpcService 注解标明
import cn.tellsea.grpcservice.proto.News;
import cn.tellsea.grpcservice.proto.NewsServiceGrpc;
import io.grpc.stub.StreamObserver;
import net.devh.boot.grpc.server.service.GrpcService;
/**
* @author Tellsea
* @date 2023/1/13
*/
@GrpcService
public class NewsService extends NewsServiceGrpc.NewsServiceImplBase {
@Override
public void hello(News.StringRequest request, StreamObserver<News.StringResponse> responseObserver) {
String name = request.getName();
News.StringResponse response = News.StringResponse.newBuilder().setResult("Hi:" + name).build();
responseObserver.onNext(response);
responseObserver.onCompleted();
}
}
修改 application.yml 配置文件
server:
port: 8080
spring:
application:
name: spring-boot-grpc-service
grpc:
server:
port: 9090
到此服务端准备完毕
2、客户端编写
客户端和服务端一样,把 proto 文件和生成的 java 类一样的处理一遍, pom.xml 中的依赖文件也使用一样的就可以了
文件生成完成之后,修改 application.yml 配置文件
server:
port: 8081
spring:
application:
name: spring-boot-grpc-client
grpc:
client:
spring-boot-grpc-service:
address: 'static://127.0.0.1:9090'
negotiation-type: plaintext
然后写一个测试控制层的接口,调用测试是有完成
import cn.tellsea.grpcclient.proto.News;
import cn.tellsea.grpcclient.proto.NewsServiceGrpc;
import net.devh.boot.grpc.client.inject.GrpcClient;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
/**
* @author Tellsea
* @date 2023/1/13
*/
@RestController
public class NewsController {
/**
* 获取调用存根
*/
@GrpcClient("spring-boot-grpc-service")
private NewsServiceGrpc.NewsServiceBlockingStub newsServiceBlockingStub;
@GetMapping("/say")
public String sayHello(String name) {
News.StringResponse response = newsServiceBlockingStub.hello(News.StringRequest
.newBuilder()
.setName(name)
.build());
return response.getResult();
}
}
当然了,我这里测试肯定是没问题的,OK,到此结束