Springboot整合Grpc,实现服务间通信

1. Grpc介绍

在 gRPC 里客户端应用可以像调用本地对象一样直接调用另一台不同的机器上服务端应用的方法,使得您能够更容易地创建分布式应用和服务。与许多 RPC 系统类似,gRPC 也是基于以下理念:定义一个服务,指定其能够被远程调用的方法(包含参数和返回类型)。在服务端实现这个接口,并运行一个 gRPC 服务器来处理客户端调用。在客户端拥有一个存根能够像服务端一样的方法。
在这里插入图片描述
gRPC 客户端和服务端可以在多种环境中运行和交互 - 从 google 内部的服务器到你自己的笔记本,并且可以用任何 gRPC 支持的语言来编写。所以,你可以很容易地用 Java 创建一个 gRPC 服务端,用 Go、Python、Ruby 来创建客户端。此外,Google 最新 API 将有 gRPC 版本的接口,使你很容易地将 Google 的功能集成到你的应用里。

1.1 传统rpc对比Grpc

  • 传统RPC框架:使用各种协议和编码方式进行通信,可能导致跨语言通信困难、性能不佳等问题;
  • GRPC框架:使用Google开发的ProtoBuf进行序列化、并通过http/2(多路复用)进行通信,通信效率更加高效;

1.2 GRPC的优势

  • 高性能:使用二进制的ProtoBuf编码和http/2多路复用机制等技术,实现低延迟和高吞吐的通信;
  • 支持多语言:C++、Java、Python、Go等等;
  • 强类型:使用ProtoBuf定义消息和接口,消除了手动解析数据的麻烦;
  • 双向流式通信:GRPC支持双向流式传输,适用于实时性要求高的场景;
  • 自动代码生成:根据定义好的服务接口和消息,GRPC自动生成客户端和服务端的代码,简化开发流程;

1.3 GRPC在分布式系统中的应用场景

  • 微服务通信;
  • 跨数据中心通信;
  • 实时通信;

java实现Grpc调用

1. Java项目简介

在这里插入图片描述

2. study_GRPC父项目

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

    <!-- 第一步:引入核心依赖,父项目 -->
    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.4.3</version>
    </parent>

    <groupId>org.example</groupId>
    <artifactId>study_GRPC</artifactId>
    <packaging>pom</packaging>
    <version>1.0-SNAPSHOT</version>
    <!-- 三个子模块 -->
    <modules>
        <module>GRPC_service</module>
        <module>GRPC_client</module>
        <module>springboot-grpc-lib</module>
    </modules>

    <properties>
        <maven.compiler.source>8</maven.compiler.source>
        <maven.compiler.target>8</maven.compiler.target>
    </properties>

    <dependencies>
        <!-- 第二步:引入web项目依赖,会导入tomcat等依赖启动Springboot
        该依赖会引入 @Service @Component @RestController tomcat等等
        -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
    </dependencies>

</project>

3. springboot-grpc-lib子模块

3.1 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">
    <parent>
        <artifactId>study_GRPC</artifactId>
        <groupId>org.example</groupId>
        <version>1.0-SNAPSHOT</version>
    </parent>
    <modelVersion>4.0.0</modelVersion>

    <artifactId>springboot-grpc-lib</artifactId>

    <properties>
        <maven.compiler.source>8</maven.compiler.source>
        <maven.compiler.target>8</maven.compiler.target>
        <java.version>8</java.version>
        <protobuf.version>3.23.4</protobuf.version>
        <grpc.version>1.26.0</grpc.version>
    </properties>


    <dependencies>
        <!-- https://mvnrepository.com/artifact/com.google.protobuf/protobuf-java -->
        <dependency>
            <groupId>com.google.protobuf</groupId>
            <artifactId>protobuf-java</artifactId>
            <version>${protobuf.version}</version>
        </dependency>
        <!-- grpc server和spring-boot集成框架 -->
        <dependency>
            <groupId>net.devh</groupId>
            <artifactId>grpc-server-spring-boot-starter</artifactId>
            <version>2.14.0.RELEASE</version>
        </dependency>

        <!-- grpc client和spring-boot集成框架 -->
        <dependency>
            <groupId>net.devh</groupId>
            <artifactId>grpc-client-spring-boot-starter</artifactId>
            <version>2.14.0.RELEASE</version>
        </dependency>
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <version>1.18.22</version>
            <optional>true</optional>
        </dependency>
    </dependencies>

    <build>

        <!-- os系统信息插件, protobuf-maven-plugin需要获取系统信息下载相应的protobuf程序 -->
        <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>
                    <!--os.detected.classifier属性是通过如上os-maven-plugin插件获取的-->
                    <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>

                    <!-- proto文件目录 -->
                    <protoSourceRoot>${project.basedir}/src/main/java/com/cxp/generateProto</protoSourceRoot>
                    <!-- 生成的Java文件目录,这里指定到这一级就可以咯,proto文件有基于package指定 -->
                    <outputDirectory>${project.basedir}/src/main/java</outputDirectory>
                    <clearOutputDirectory>false</clearOutputDirectory>
                </configuration>
                <executions>
                    <execution>
                        <goals>
                            <goal>compile</goal>
                            <goal>compile-custom</goal>
                        </goals>
                    </execution>
                </executions>
            </plugin>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
                <version>2.4.3</version>
                <configuration>
                    <excludes>
                        <exclude>
                            <groupId>org.projectlombok</groupId>
                            <artifactId>lombok</artifactId>
                        </exclude>
                    </excludes>
                </configuration>
            </plugin>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-compiler-plugin</artifactId>
                <version>3.8.1</version>
                <configuration>
                    <source>8</source>
                    <target>8</target>
                </configuration>
            </plugin>
        </plugins>
    </build>

</project>
3.2 项目目录

在这里插入图片描述

3.3 hello.proto
// 说明使用的是:proto3语法
syntax = "proto3";

// java_package表示生成java代码的包名
option java_package = "com.cxp.generateProto.protogen";
// java_multiple_files = true 表示生成多个java文件,若不设置该属性,则只会生成一个java文件
option java_multiple_files = true;
// java_outer_classname表示包含message描述的java文件的类名
 option java_outer_classname = "HelloWorldProto";

// 定义一个服务,服务中可以编写多个方法。方法可以接受客户端的参数,再返回服务端的响应。
service HelloWorld {
  // 方法:接受 HelloRequest,返回 HelloResp
  rpc sayHello(HelloRequest) returns (HelloResp) {}
}

// message关键字表示结构体
message HelloRequest {
  // 赋值是为了定义这个变量在message中的位置
  string name = 1;
  int32 id = 2;
}

message HelloResp {
  string school = 1;
  string address = 2;
  int32 age = 3;
}
3.4 生成protobuf文件

在这里插入图片描述

4. GRPC_service子模块

4.1 pom.xml文件
 <dependencies>
     <dependency>
         <groupId>org.example</groupId>
         <artifactId>springboot-grpc-lib</artifactId>
         <version>1.0-SNAPSHOT</version>
     </dependency>
 </dependencies>
4.2 application.yml文件
server:
  port: 8080

grpc:
  server:
    # 指定Grpc暴露的端口,后续客户端通过这个端口访问
    port: 9090
4.3 Grpc接口实现类

一定记得加@GrpcService注解,表明这个是Grpc服务接口的实现类!!!

import com.cxp.generateProto.protogen.HelloRequest;
import com.cxp.generateProto.protogen.HelloResp;
import com.cxp.generateProto.protogen.HelloWorldGrpc;
import io.grpc.stub.StreamObserver;
import net.devh.boot.grpc.server.service.GrpcService;

/**
 * @Author: Thomas
 * @Date: 2023-10-05  21:56:45
 * @Description:
 */
@GrpcService
public class HelloWorldProtoImpl extends HelloWorldGrpc.HelloWorldImplBase {
    @Override
    public void sayHello(HelloRequest request, StreamObserver<HelloResp> responseObserver) {
        String name = request.getName();
        int id = request.getId();
        System.out.println(name + " ---------------------- " + id);
        /**
         * 这里可以写具体的业务逻辑进行实现!!!!
         */
        HelloResp helloResp = HelloResp.newBuilder()
                .setSchool("DMU")
                .setAddress("贵州遵义")
                .setAge(123)
                .build();
        responseObserver.onNext(helloResp);
        responseObserver.onCompleted();
    }
}
4.4 项目目录

在这里插入图片描述

5. GRPC_client子模块

5.1 pom.xml文件
    <dependencies>
        <dependency>
            <groupId>org.example</groupId>
            <artifactId>springboot-grpc-lib</artifactId>
            <version>1.0-SNAPSHOT</version>
            <exclusions>
                <!-- 排除GRPC的服务器依赖,避免客户端也需要暴露Grpc服务端口 -->
                <exclusion>
                        <groupId>net.devh</groupId>
                        <artifactId>grpc-server-spring-boot-starter</artifactId>
                </exclusion>
            </exclusions>
        </dependency>
    </dependencies>
5.2 基于GRPC server的URL直接调用【非Springboot调用】
public class FramelessGrpcClient {
    public static void main(String[] args) {
        ManagedChannel managedChannel = ManagedChannelBuilder.forAddress("localhost", 9090).usePlaintext().build();
        HelloWorldGrpc.HelloWorldBlockingStub heelloWorldService = HelloWorldGrpc.newBlockingStub(managedChannel);
        HelloRequest helloRequest = HelloRequest.newBuilder()
                .setName("cxplovezm")
                .setId(10000)
                .build();
        System.out.println("get response-------->");
        HelloResp helloResp = heelloWorldService.sayHello(helloRequest);
        System.out.println(helloResp);
        System.out.println(helloResp.getSchool() + " " + helloResp.getAddress() + " " + helloResp.getAge());
    }
}
  • 测试
  1. 启动服务端
    在这里插入图片描述
  2. 运行 FramelessGrpcClient 代码
    在这里插入图片描述
5.3 基于Springboot的IOC注入调用
5.3.1 application.yml文件
server:
  port: 8081

grpc:
  client:
    # 可以申明多个Grpc服务的ip和端口,后续注入通过 userClient 注入
    userClient:
      negotiationType: PLAINTEXT
      address: localhost:9090
5.3.2 controller控制器
@RestController
@RequestMapping("/hello")
public class HelloController {

    @Resource
    private HelloWorld helloWorld;

    @GetMapping("/world")
    public String getWorld() {
        System.out.println(" ---------- 进入Springboot的Grpc的client -----------");
        return helloWorld.getHelloWorld();
    }

}
5.3.3 服务接口
  • 服务
public interface HelloWorld {

    String getHelloWorld();

}
  • 实现类
@Service
public class HelloworldImpl implements HelloWorld {

    // 注意:这里的userClient需要和applicaiotn.yml中的userClient一致,当调用多个grpc服务时候,可以用于区分!!!
    @GrpcClient("userClient")
    private HelloWorldGrpc.HelloWorldBlockingStub helloWorldClient;

    @Override
    public String getHelloWorld() {
        HelloRequest helloRequest = HelloRequest.newBuilder()
                .setName("cxplovezm")
                .setId(10000)
                .build();
        HelloResp helloResp = helloWorldClient.sayHello(helloRequest);
        return helloResp.getSchool() + " " + helloResp.getAddress() + "  " + helloResp.getAge();
    }
}
5.3.4 测试
  • 客户端启动类
@SpringBootApplication
public class GRPCClientApplication {
    public static void main(String[] args) {
        SpringApplication.run(GRPCClientApplication.class, args);
    }
}
  1. 启动服务器;
    在这里插入图片描述
  1. 启动客户端;
    在这里插入图片描述
  1. 浏览器输入:http://localhost:8081/hello/world
    在这里插入图片描述

成功!!!!

回答: 在将gRPC整合Spring Boot中时,首先需要创建一个Spring Boot项目作为父工程,并命名为springboot_grpc。然后,您可以使用proto3版本的协议缓冲与gRPC一起使用,这样可以避免与proto2客户端通信时的兼容性问题,并允许您在全系列gRPC支持的语言中使用。gRPC是一个由Google发起的开源远程过程调用系统,基于HTTP/2协议传输,基于protobuf 3.x,并且基于Netty 4.x。它提供了高性能的跨语言RPC框架。在整合gRPC时,您需要设置跨平台序列化和流式数据传输,并确保操作环境满足要求,包括系统、架构、环境和仓库等。您可以使用Ubuntu 18.04作为操作系统,Linux-x86_64作为架构,JDK 8作为环境,并使用Maven和IntelliJ IDEA作为构建工具和开发环境。在环境准备方面,您需要安装Protobuf以支持gRPC的使用。123 #### 引用[.reference_title] - *1* [Springboot整合gRPC](https://blog.csdn.net/weixin_40395050/article/details/96971708)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v92^chatsearchT3_1"}} ] [.reference_item] - *2* [springboot整合gprc 传输对象](https://blog.csdn.net/qq_28423433/article/details/79108976)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v92^chatsearchT3_1"}} ] [.reference_item] - *3* [SpringBoot整合grpc](https://blog.csdn.net/weixin_44504392/article/details/122230502)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v92^chatsearchT3_1"}} ] [.reference_item] [ .reference_list ]
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值