spring 和 grpc 的整合

spring 和 grpc 的整合

首先我们要知道 grpc 中我们在使用的时候用到了 grpc 的那些东西

  • dil 的编写
  • serverimpl
  • serverbuilder
    • addService
  • 客户端的 stub 编写

这里面我们看一下我们那些地方可能需要 spring 帮我们管理,那些地方我们需要自己来管理呢?比如服务的构建 spring 是可以帮我么做的,而且 addServer 可以通过注解的方式自动发布服务,但是 server 的 imp 我们是需要自己来实现的,服务的端口可以通过 properties 的方式来做自动配置和默认值的设置。注解的标识 spring 使用 @GrpcService

服务端搭建开发环境

  1. spring的开发环境我们需要搭建,这个可以直接在 idea 创建,我就不记录和展示
  2. 引入 grpc spring 相关的依赖
<dependency>
    <groupId>net.devh</groupId>
    <artifactId>grpc-server-spring-boot-starter</artifactId>
    <version>2.15.0.RELEASE</version>
    <exclusions>
        <exclusion>
            <groupId>com.google.protobuf</groupId>
            <artifactId>protobuf-java</artifactId>
        </exclusion>
    </exclusions>
</dependency>

<dependency>
    <groupId>com.google.protobuf</groupId>
    <artifactId>protobuf-java</artifactId>
    <version>3.25.5</version>
</dependency>

因为这是一个 grpc 的 server 所以并不需要使用 java-web 相关的服务,我们可以移除相关的依赖,并且在配置中禁用 web 相关的内容

配置 & 移除 web 相关的内容

grpc:
  server:
    port: 8888

-- 禁用 web 的服务
spring:
  application:
    name: grpc-server
  main:
    web-application-type: none
server:
  port: 9999

移除对应的依赖在 pom 文件中

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-web</artifactId>
    <exclusions>
        <exclusion>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-tomcat</artifactId>
        </exclusion>
        <exclusion>
            <artifactId>logback-classic</artifactId>
            <groupId>ch.qos.logback</groupId>
        </exclusion>
    </exclusions>
</dependency>

这个时候我们就可以使用了,使用注解 @GrpcServer 使其在 springboot 中可以被注入 IOC 容器,然后就是很传统的实现 **ImplBase 并且她也会帮我们把这个服务发布到 GRPC 服务中 addServer 这样 springboot 启动就会自动提供服务接受 grpc client 发送来的请求。

@GrpcService
public class OnceMessageServiceImpl extends BiRpcServiceGrpc.BiRpcServiceImplBase {

    private final Logger log = LoggerFactory.getLogger(OnceMessageServiceImpl.class);

    @Override
    public void getOnceMessage(final BiService.OnceMessageRequest request, final StreamObserver<BiService.OnceMessageResponse> responseObserver) {
        log.info("receive client request msg -> {}", request.getContent());
        responseObserver.onNext(
                BiService.OnceMessageResponse.newBuilder().setContent(UUID.randomUUID().toString()).build()
        );
        responseObserver.onCompleted();
    }
}
syntax = "proto3";

option java_package = "com.rpc.grpc.bi";
option java_multiple_files = false;
option java_outer_classname = "BiService";

message OnceMessageRequest {
  string content = 1;
}

message OnceMessageResponse {
  string content = 1;
}

service BiRpcService {
  // 注意这里因为我们使用 future 的方式来通讯,这就不可以使用 stream,只能使用简单的 rpc
  rpc getOnceMessage(OnceMessageRequest) returns (OnceMessageResponse) {}
}

service NewBiRpcService {
  // 注意这里因为我们使用 future 的方式来通讯,这就不可以使用 stream,只能使用简单的 rpc
  rpc newGetOnceMessage(OnceMessageRequest) returns (OnceMessageResponse) {}
}

客户端搭建

引入依赖

<dependency>
    <groupId>net.devh</groupId>
    <artifactId>grpc-client-spring-boot-starter</artifactId>
    <version>3.0.0.RELEASE</version>
</dependency>

增加配置

spring:
  application:
    name: grpc-rpc-boot-client
grpc:
  client:
    bi_server:
      address: static://localhost:8888
      negotiation-type: plaintext

server:
  port: 8989

编码

由于 spring 以及对客户端的服务创建,等配置做了封装,所以我们并不需要关心 channel 的创建,我们直接注入对应的 stub(这里有三种 stub,分别是 future,stub,block),直接使用注解 @GrpcClient 然后在里面放我们在配置文件中配置的服务名称,直接就可以通过 stub 调用了,然后 channel 的关闭等操作我们也不用关心,这个已经做好了相关的封装,使用者直接关心业务层面的逻辑就可以了。

public class BiRpcServerBlockStub {

    @GrpcClient("bi_server")
    private BiRpcServiceGrpc.BiRpcServiceBlockingStub biRpcServiceBlockingStub;

    @GetMapping
    public Object getUserInfo(String msg) {
        final BiService.OnceMessageResponse onceMessage = biRpcServiceBlockingStub.getOnceMessage(
                BiService.OnceMessageRequest.newBuilder()
                        .setContent(msg).build()
        );

        return onceMessage.getContent();
    }
}

大家可以关注我的WX
在这里插入图片描述

### Spring Cloud 中集成 gRPC 服务 #### Maven 配置 为了在 Spring Cloud 项目中成功集成 gRPC,首先需要设置项目的 `pom.xml` 文件来引入必要的依赖项。这通常涉及到添加特定于 gRPC Protocol Buffers 编译器插件的支持[^4]。 ```xml <dependencies> <!-- gRPC dependency --> <dependency> <groupId>io.grpc</groupId> <artifactId>grpc-netty-shaded</artifactId> <version>${grpc.version}</version> </dependency> <!-- Protobuf Java runtime library and compiler plugin --> <dependency> <groupId>com.google.protobuf</groupId> <artifactId>protobuf-java</artifactId> <version>${protobuf.version}</version> </dependency> <!-- Other dependencies... --> </dependencies> <!-- Plugin configuration for compiling .proto files into Java classes --> <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:${protobuf.version}:exe:${os.detected.classifier}</protocArtifact> <pluginId>grpc-java</pluginId> <pluginArtifact>io.grpc:protoc-gen-grpc-java:${grpc.version}:exe:${os.detected.classifier}</pluginArtifact> </configuration> <executions> <execution> <goals> <goal>compile</goal> <goal>compile-custom</goal> </goals> </execution> </executions> </plugin> </plugins> </build> ``` #### 定义 Proto 文件 创建 `.proto` 文件用于描述服务接口以及消息结构。这些文件应当放置在一个名为 `common` 的模块内以便被其他模块所共享使用。 ```protobuf syntax = "proto3"; option java_multiple_files = true; package com.example; service ExampleService { rpc SayHello (HelloRequest) returns (HelloResponse); } message HelloRequest { string name = 1; } message HelloResponse { string message = 1; } ``` #### YAML 配置 对于服务器端而言,在应用程序的配置文件 (`application.yml`) 中指定监听地址其他必要参数;而对于客户端,则需指明目标主机名端口,并可选地设定连接选项如协商类型为纯文本模式以简化开发过程。 **Server-side Configuration** ```yaml server: port: 9090 grpc: server: port: ${server.port} ``` **Client-side Configuration** ```yaml spring: application: name: example-client grpc: negotiation-type: plaintext name-resolver-provider: dns-unresolved enable-channelz: false keepalive-time: 1h max-inbound-message-size: 4MB ``` #### 实现 Service 类 编写具体的业务逻辑处理程序并将其注册到 gRPC 服务器上作为远程调用的目标对象实例之一。 ```java @Service public class ExampleServiceImpl extends ExampleGrpc.ExampleImplBase { @Override public void sayHello(HelloRequest request, StreamObserver<HelloResponse> responseObserver) { String greeting = new StringBuilder().append("Hello ").append(request.getName()).toString(); HelloResponse reply = HelloResponse.newBuilder() .setMessage(greeting).build(); responseObserver.onNext(reply); responseObserver.onCompleted(); } } ``` #### 启动 Server Client 应用 最后一步是在各自的应用入口处启动相应的 gRPC 组件——通过继承自 `SpringBootServletInitializer` 或者直接利用 `@SpringBootApplication` 注解标记主类的方式完成初始化工作。 ```java @SpringBootApplication @EnableDiscoveryClient public class GrpcApplication { private static final Logger logger = LoggerFactory.getLogger(GrpcApplication.class); public static void main(String[] args) throws Exception { SpringApplication.run(GrpcApplication.class, args); } @Bean public ServerFactoryBean createGrpcServer() { return NettyServerBuilder.forPort(port) .addService(new ExampleServiceImpl()) .build(); } } ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值