spring boot 集成 gRPC 系列1

@[toc]

目录

一、环境准备

二、gRPC项目构建

创建proto文件

生成Java类

创建模块local-server(gRPC服务端)

创建模块local-client(gRPC客户端)

调用效果



一、环境准备


安装protocbuf
下载地址

https://github.com/protocolbuffers/protobuf/releases

选择对应的版本下载安装,这里我选择21.1
选择对应的压缩包解压

spring boot 集成 gRPC 系列1_第1张图片
配置环境变量
变量名 :PROTOCBUF_HOME
变量值:D:\protoc-21.1-win64

 spring boot 集成 gRPC 系列1_第2张图片

找到系统变量中的path变量,选中后点击编辑,新增:%PROTOBUF_HOME%\bin

安装protocbuf插件

Protobuf - IntelliJ IDEs Plugin | Marketplace
从idea官网下载插件

spring boot 集成 gRPC 系列1_第3张图片

 选择idea对应的版本下载

spring boot 集成 gRPC 系列1_第4张图片


二、gRPC项目构建

 项目目录结构


spring boot 集成 gRPC 系列1_第5张图片

项目结构

spring boot 集成 gRPC 系列1_第6张图片
创建maven父工程spring-boot-grpc
完整pom.xml



    4.0.0
    pom

    
        spring-boot-grpc-lib
        local-server
        local-client
    

    
        org.springframework.boot
        spring-boot-starter-parent
        2.6.1
         
    
    org.example
    spring-boot-grpc
    1.0-SNAPSHOT

    
        
            org.springframework.boot
            spring-boot-starter-web
        

        
            org.springframework.boot
            spring-boot-starter-test
            test
        

    


    
        
            
                org.apache.maven.plugins
                maven-compiler-plugin
                3.8.1
                
                    1.8
                    1.8
                    UTF-8
                
            
            
                org.springframework.boot
                spring-boot-maven-plugin
                2.6.1
            
        
    


创建模块spring-boot-grpc-lib
此模块负责将.proto文件生成Java对应的类与接口

根据官方文档

选择对应的版本查看README.md

可以根据提交历史查看具体proto版本对应的pom.xml

完整pom.xml



    
        org.example
        spring-boot-grpc
        1.0-SNAPSHOT
    
    4.0.0
    com.example
    spring-boot-grpc-lib
    0.0.1-SNAPSHOT
    spring-boot-grpc-lib
    Demo project for Spring Boot

    
        1.8
        UTF-8
        UTF-8
    

    
        
            io.grpc
            grpc-netty-shaded
            1.42.1
        
        
            io.grpc
            grpc-protobuf
            1.42.1
        
        
            io.grpc
            grpc-stub
            1.42.1
        
         
            org.apache.tomcat
            annotations-api
            6.0.53
            provided
        
        
            com.google.protobuf
            protobuf-java
            3.17.2
        
        
            com.google.protobuf
            protobuf-java-util
            3.17.2
        
        
            javax.annotation
            javax.annotation-api
            1.3.2
        
    

    
        
            
                io.grpc
                grpc-bom
                1.42.2
                pom
                import
            
        
    

    
        
            
                kr.motd.maven
                os-maven-plugin
                1.6.2
            
        
        
            
                org.xolstice.maven.plugins
                protobuf-maven-plugin
                0.6.1
                
                    com.google.protobuf:protoc:3.17.2:exe:${os.detected.classifier}
                    grpc-java
                    io.grpc:protoc-gen-grpc-java:1.42.1:exe:${os.detected.classifier}
                
                
                    
                        
                            compile
                            compile-custom
                        
                    
                
            
        
    



创建proto文件

在spring-boot-grpc-lib模块的src/main/proto目录下新增名为helloworld.proto的文件

这里面定义了一个gRPC服务,里面含有一个接口,并且还有这个接口的入参和返回结果的定义

proto文件夹需要在 File -> ProjectStructure 中将其标记为sources

spring boot 集成 gRPC 系列1_第7张图片
helloworld.proto完整代码

syntax = "proto3"; // 协议版本

// 选项配置
option java_multiple_files = true;
option java_package = "com.example.springbootgrpclib.grpc.protobuf";
option java_outer_classname = "SimpleProto";

service Simple {
    // 简单gRPC
    rpc OneToOne (MyRequest) returns (MyResponse) {
    }
}

message MyRequest {
    string name = 1;

    int32 value = 2;
}

message MyResponse {
    string message = 1;

    int64 result = 2;
}


生成Java类

idea 单击编译类

spring boot 集成 gRPC 系列1_第8张图片

生成对应的类并且将其复制到spring-boot-grpc-lib下

spring boot 集成 gRPC 系列1_第9张图片

spring-boot-grpc-lib结构:

spring boot 集成 gRPC 系列1_第10张图片

创建模块local-server(gRPC服务端)


在父工程下面新建名为local-server的springboot模块,

添加gRPC 服务端 Maven 依赖和spring-boot-grpc-lib模块

完整pom.xml



    4.0.0
    
        org.example
        spring-boot-grpc
        1.0-SNAPSHOT
    
    com.example
    local-server
    0.0.1-SNAPSHOT
    local-server
    Demo project for Spring Boot

    
        11
        UTF-8
        UTF-8
        2.6.1
    

    
        
        
            org.projectlombok
            lombok
            true
        
        
        
            net.devh
            grpc-server-spring-boot-starter
            2.13.0.RELEASE
        
        
        
            com.example
            spring-boot-grpc-lib
            0.0.1-SNAPSHOT
        
    


springboot配置文件 application.yml

spring:
  application:
    name: spring-boot-grpc-server
# gRPC有关的配置,这里只需要配置服务端口号
grpc:
  server:
    port: 9898
server:
  port: 8080

增加启动类RpcServerApplication

package com.example.localserver;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

@SpringBootApplication
public class RpcServerApplication {

	public static void main(String[] args) {
		SpringApplication.run(RpcServerApplication.class, args);
	}

}


在service类中将gRPC服务对外暴露出去

完整代码如下

package com.example.localserver.server;

import com.example.springbootgrpclib.grpc.protobuf.MyRequest;
import com.example.springbootgrpclib.grpc.protobuf.MyResponse;
import com.example.springbootgrpclib.grpc.protobuf.SimpleGrpc;
import io.grpc.stub.StreamObserver;
import lombok.extern.slf4j.Slf4j;
import net.devh.boot.grpc.server.service.GrpcService;


@GrpcService
@Slf4j
public class GrpcServerService extends SimpleGrpc.SimpleImplBase {

    @Override
    public void oneToOne(MyRequest request, StreamObserver responseObserver) {
        log.info("接收客户端数据{}", request);
        MyResponse response = MyResponse.newBuilder().setMessage( request.getName()).build();
        responseObserver.onNext(response);
        responseObserver.onCompleted();
    }
    
}



上述GrpcServerService.java中有几处需要注意:

是使用@GrpcService注解,再继承SimpleImplBase,这样就可以借助grpc-server-spring-boot-starter库将oneToOne暴露为gRPC服务;

SimpleImplBase是前文中根据proto自动生成的java代码,在spring-boot-grpc-lib模块中;

oneToOne方法中处理完毕业务逻辑后,调用responseObserver.onNext方法填入返回内容;

调用responseObserver.onCompleted方法表示本次gRPC服务完成;

至此,gRPC服务端编码就完成了,服务端流、客户端流和双向流在后面介绍。

创建模块local-client(gRPC客户端)


在父工程grpc-turtorials下面新建名为local-client的模块

添加gRPC客户端 Maven 依赖和spring-boot-grpc-lib模块

完整pom.xml



    4.0.0
    
        org.example
        spring-boot-grpc
        1.0-SNAPSHOT
    
    com.example
    local-client
    0.0.1-SNAPSHOT
    local-client
    Demo project for Spring Boot

    
        11
        UTF-8
        UTF-8
        2.6.1
    

    
        
        
        
            net.devh
            grpc-client-spring-boot-starter
            2.13.0.RELEASE
        
        
        
            com.example
            spring-boot-grpc-lib
            0.0.1-SNAPSHOT
        
        
        
            org.projectlombok
            lombok
            true
        
    


springboot配置文件 application.yml:

server:
  port: 8088
spring:
  application:
    name: local-client

grpc:
  client:
    # gRPC配置的名字,GrpcClient注解会用到
    local-grpc-server:
      # gRPC服务端地址
      address: 'static://127.0.0.1:9898'
      enableKeepAlive: true
      keepAliveWithoutCalls: true
      negotiationType: plaintext

启动类RpcClientApplication

package com.example.localclient;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

@SpringBootApplication
public class RpcClientApplication {

	public static void main(String[] args) {
		SpringApplication.run(RpcClientApplication.class, args);
	}

}



服务类GrpcClientService

package com.example.localclient.service;

import com.example.springbootgrpclib.grpc.protobuf.MyRequest;
import com.example.springbootgrpclib.grpc.protobuf.MyResponse;
import com.example.springbootgrpclib.grpc.protobuf.SimpleGrpc;
import io.grpc.StatusRuntimeException;
import lombok.extern.slf4j.Slf4j;
import net.devh.boot.grpc.client.inject.GrpcClient;
import org.springframework.stereotype.Service;

@Service
@Slf4j
public class GrpcClientService {

    @GrpcClient("local-grpc-server")
    private SimpleGrpc.SimpleBlockingStub simpleStub;

    public String oneToOne(final String name) {
        try {
            final MyResponse response = this.simpleStub.oneToOne(MyRequest.newBuilder().setName(name).build());
            return response.getMessage();
        } catch (final StatusRuntimeException e) {
            return "FAILED with " + e.getStatus().getCode().name();
        }
    }
}



上述GrpcClientService类有几处要注意的地方:

用@Service将GrpcClientService注册为spring的普通bean实例;

用@GrpcClient修饰SimpleBlockingStub,这样就可以通过grpc-client-spring-boot-starter库发起gRPC调用,被调用的服务端信息来自名为local-grpc-server的配置;

SimpleBlockingStub来自前文中根据helloworld.proto生成的java代码;

SimpleBlockingStub.oneToOne方法会远程调用local-server应用的gRPC服务;

新增controller层验证gRPC服务调用能否成功

package com.example.localclient.controller;

import com.example.localclient.service.GrpcClientService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

import java.util.List;

/**
 * @author cdj
 * @date 2022/4/11 - 17:36
 **/
@RestController
public class GrpcClientController {

    @Autowired
    private GrpcClientService grpcClientService;

    @RequestMapping("/oneToOne")
    public String oneToOne(@RequestParam(defaultValue = "name") String name) {
        return grpcClientService.oneToOne(name);
    }

}

调用效果

http://127.0.0.1:8088/oneToOne?name=rpc-test

spring boot 集成 gRPC 系列1_第11张图片

你可能感兴趣的:(java,intellij-idea,开发语言,rpc)