Java版gRPC的使用之一:简单的gRPC搭建

一、环境准备

安装protocbuf

下载地址

选择对应的版本下载安装,这里我选择3.17.2
在这里插入图片描述选择对应的压缩包解压

在这里插入图片描述
配置环境变量
变量名 :PROTOCBUF_HOME
变量值:D:\protoc-3.19.1-win64

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

在这里插入图片描述

安装protocbuf插件

从idea官网下载插件
在这里插入图片描述

二、gRPC项目构建

项目结构

在这里插入图片描述

创建maven父工程spring-boot-grpc

完整pom.xml

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <packaging>pom</packaging>

    <modules>
        <module>spring-boot-grpc-lib</module>
        <module>local-server</module>
        <module>local-client</module>
    </modules>

    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.6.1</version>
        <relativePath/> <!-- lookup parent from repository -->
    </parent>
    <groupId>org.example</groupId>
    <artifactId>spring-boot-grpc</artifactId>
    <version>1.0-SNAPSHOT</version>

    <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>

    </dependencies>


    <build>
        <plugins>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-compiler-plugin</artifactId>
                <version>3.8.1</version>
                <configuration>
                    <source>11</source>
                    <target>11</target>
                    <encoding>UTF-8</encoding>
                </configuration>
            </plugin>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
                <version>2.6.1</version>
            </plugin>
        </plugins>
    </build>
</project>

创建模块spring-boot-grpc-lib

此模块负责将.proto文件生成Java对应的类与接口

根据官方文档
在这里插入图片描述
选择对应的版本查看README.md

可以根据提交历史查看具体proto版本对应的pom.xml
在这里插入图片描述
在这里插入图片描述

完整pom.xml

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
    <parent>
        <groupId>org.example</groupId>
        <artifactId>spring-boot-grpc</artifactId>
        <version>1.0-SNAPSHOT</version>
    </parent>
    <modelVersion>4.0.0</modelVersion>
    <groupId>com.example</groupId>
    <artifactId>spring-boot-grpc-lib</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <name>spring-boot-grpc-lib</name>
    <description>Demo project for Spring Boot</description>

    <properties>
        <java.version>11</java.version>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
    </properties>

    <dependencies>
        <dependency>
            <groupId>io.grpc</groupId>
            <artifactId>grpc-netty-shaded</artifactId>
            <version>1.42.1</version>
        </dependency>
        <dependency>
            <groupId>io.grpc</groupId>
            <artifactId>grpc-protobuf</artifactId>
            <version>1.42.1</version>
        </dependency>
        <dependency>
            <groupId>io.grpc</groupId>
            <artifactId>grpc-stub</artifactId>
            <version>1.42.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>
        <dependency>
            <groupId>com.google.protobuf</groupId>
            <artifactId>protobuf-java</artifactId>
            <version>3.17.2</version>
        </dependency>
        <dependency>
            <groupId>com.google.protobuf</groupId>
            <artifactId>protobuf-java-util</artifactId>
            <version>3.17.2</version>
        </dependency>
        <dependency>
            <groupId>javax.annotation</groupId>
            <artifactId>javax.annotation-api</artifactId>
            <version>1.3.2</version>
        </dependency>
    </dependencies>

    <dependencyManagement>
        <dependencies>
            <dependency>
                <groupId>io.grpc</groupId>
                <artifactId>grpc-bom</artifactId>
                <version>1.42.2</version>
                <type>pom</type>
                <scope>import</scope>
            </dependency>
        </dependencies>
    </dependencyManagement>

    <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.2:exe:${os.detected.classifier}</protocArtifact>
                    <pluginId>grpc-java</pluginId>
                    <pluginArtifact>io.grpc:protoc-gen-grpc-java:1.42.1:exe:${os.detected.classifier}</pluginArtifact>
                </configuration>
                <executions>
                    <execution>
                        <goals>
                            <goal>compile</goal>
                            <goal>compile-custom</goal>
                        </goals>
                    </execution>
                </executions>
            </plugin>
        </plugins>
    </build>
</project>

创建proto文件

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

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

proto文件夹需要在 File -> ProjectStructure 中将其标记为sources
在这里插入图片描述

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类

在这里插入图片描述
如果出现以下报错是因为无法下载对应的pom 和 exe
在这里插入图片描述

需要点击报错的最后的连接手动下载对应资源,根据路径放到maven对应的Repository中
在这里插入图片描述
生成对应的类并且将其移到spring-boot-grpc-lib下

在这里插入图片描述

spring-boot-grpc-lib结构:

在这里插入图片描述

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

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

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

完整pom.xml

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <parent>
        <groupId>org.example</groupId>
        <artifactId>spring-boot-grpc</artifactId>
        <version>1.0-SNAPSHOT</version>
    </parent>
    <groupId>com.example</groupId>
    <artifactId>local-server</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <name>local-server</name>
    <description>Demo project for Spring Boot</description>

    <properties>
        <java.version>11</java.version>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
        <spring-boot.version>2.6.1</spring-boot.version>
    </properties>

    <dependencies>
        <!--Lombok引入-->
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <optional>true</optional>
        </dependency>
        <!--gRPC服务端-->
        <dependency>
            <groupId>net.devh</groupId>
            <artifactId>grpc-server-spring-boot-starter</artifactId>
            <version>2.13.0.RELEASE</version>
        </dependency>
        <!--spring-boot-grpc-lib模块-->
        <dependency>
            <groupId>com.example</groupId>
            <artifactId>spring-boot-grpc-lib</artifactId>
            <version>0.0.1-SNAPSHOT</version>
        </dependency>
    </dependencies>
</project>

springboot配置文件 application.yml

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

在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<MyResponse> 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

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <parent>
        <groupId>org.example</groupId>
        <artifactId>spring-boot-grpc</artifactId>
        <version>1.0-SNAPSHOT</version>
    </parent>
    <groupId>com.example</groupId>
    <artifactId>local-client</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <name>local-client</name>
    <description>Demo project for Spring Boot</description>

    <properties>
        <java.version>11</java.version>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
        <spring-boot.version>2.6.1</spring-boot.version>
    </properties>

    <dependencies>
        
        <!--gRPC客户端-->
        <dependency>
            <groupId>net.devh</groupId>
            <artifactId>grpc-client-spring-boot-starter</artifactId>
            <version>2.13.0.RELEASE</version>
        </dependency>
        <!--spring-boot-grpc-lib模块-->
        <dependency>
            <groupId>com.example</groupId>
            <artifactId>spring-boot-grpc-lib</artifactId>
            <version>0.0.1-SNAPSHOT</version>
        </dependency>
        <!--lombok-->
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <optional>true</optional>
        </dependency>
    </dependencies>
</project>

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

服务类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);
    }

}

  • 5
    点赞
  • 30
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
`io.grpc:protoc-gen-grpc-java:1.0.0:exe:${os.detected.classifier}` 是一个 Maven 坐标,用于使用 gRPC 的 Protocol Buffers 编译器插件来生成 gRPC 相关的 Java 代码。 这个坐标指定了以下部分: - `io.grpc` 是 Maven 组织 ID,表示该插件是由 gRPC 提供的。 - `protoc-gen-grpc-java` 是插件的名称,用于生成 gRPC 相关的 Java 代码。 - `1.0.0` 是插件的本号,表示要使用的插件本。 - `exe:${os.detected.classifier}` 指定了插件的文件类型和操作系统相关的后缀。 `${os.detected.classifier}` 是一个 Maven 变量,用于根据操作系统自动选择相应的插件文件。它会根据当前操作系统选择适当的文件后缀,例如在 Windows 上是 `.exe`,在 Linux 上是 `.linux-x86_64`。 通过在 Maven 项目的 `pom.xml` 文件中添加该依赖项,您可以在构建过程中自动下载并使用该插件来生成 gRPCJava 代码。例如: ```xml <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.0.0:exe:${os.detected.classifier}</pluginArtifact> </configuration> <executions> <execution> <goals> <goal>compile</goal> <goal>compile-custom</goal> </goals> </execution> </executions> </plugin> </plugins> ``` 这样配置后,您可以使用 `mvn compile` 命令来自动生成 gRPCJava 代码。生成的代码将位于 `target/generated-sources/protobuf` 目录下。 请确保您的 Maven 项目中已经包含了正确的依赖项,并且配置文件中的本号与您所需的本一致。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值