SpringBoot集成Dubbo启用gRPC协议

简介: 本文记录下SpringBoot集成Dubbo启用gRPC协议,以及与原生 gRPC 在代码编写过程中的区别。

本文记录下SpringBoot集成Dubbo启用gRPC协议,以及与原生 gRPC 在代码编写过程中的区别。


2023.6.30 补充:Dubbo 官方文档开放,为开发者使用提供友好的支持。

前言

Dubbo 在 2.7.5 版本开始支持原生 gRPC 协议,对于计划使用 HTTP/2 通信或者期望 gRPC 协议支持服务治理能力的,都可以考虑接入 Dubbo 体系启用 gRPC 协议。

由于官网给的 代码示例 是基于 spring,现在基本上都是基于SpringBoot开发,所以本文提供一下 SpringBoot 的代码示例。

此外还会简单说明 Dubbo 支持的原生 gRPC 协议与原生 gRPC 协议在代码开发时的区别。

如果对gRPC协议不了解的,后续文章会有更新,请持续关注。

项目结构

根据现在微服务开发的常见方式,先搭建一个项目,结构如下
在这里插入图片描述

这样的项目结构可以将服务的声明和实现隔离开,如果有 client 调用,直接添加api module 的依赖即可。

代码示例

项目结构确定好后需要做三件事

  1. 在项目中需要用到 grpc 和 dubbo 相关依赖,所以在父工程中的 pom.xml 文件添加两者的 BOM。
  2. gRPC 支持的序列化协议为 protobuf,我们在 api module 下添加 gRPC 所需依赖、插件以及 proto IDL文件。
  3. 在 service module 添加相关配置并进行 api service 的实现。

详细代码如下:

父工程

父工程中的 pom.xml 文件添加 grpc 和 dubbo 的 BOM。
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>
    <groupId>com.demo</groupId>
    <artifactId>nava</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <packaging>pom</packaging>
    <name>nava</name>
    <description>Demo project for Spring Boot</description>
    <properties>
        <java.version>1.8</java.version>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
        <dubbo.version>3.1.7</dubbo.version>
        <grpc.version>1.44.1</grpc.version>
        <spring-boot.version>2.6.11</spring-boot.version>
    </properties>

    <modules>
        <module>nava-api</module>
        <module>nava-service</module>
    </modules>

    <dependencyManagement>
        <dependencies>
            <dependency>
                <groupId>io.grpc</groupId>
                <artifactId>grpc-bom</artifactId>
                <version>${grpc.version}</version>
                <type>pom</type>
                <scope>import</scope>
            </dependency>
            <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-dependencies</artifactId>
                <version>${spring-boot.version}</version>
                <type>pom</type>
                <scope>import</scope>
            </dependency>
            <dependency>
                <groupId>org.apache.dubbo</groupId>
                <artifactId>dubbo-bom</artifactId>
                <version>${dubbo.version}</version>
                <type>pom</type>
                <scope>import</scope>
            </dependency>
            <dependency>
                <groupId>com.demo</groupId>
                <artifactId>nava-api</artifactId>
                <version>0.0.1-SNAPSHOT</version>
            </dependency>
            <dependency>
                <groupId>com.demo</groupId>
                <artifactId>nava-service</artifactId>
                <version>0.0.1-SNAPSHOT</version>
            </dependency>
        </dependencies>
    </dependencyManagement>

    <build>
        <plugins>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-compiler-plugin</artifactId>
                <version>3.8.1</version>
                <configuration>
                    <source>1.8</source>
                    <target>1.8</target>
                    <encoding>UTF-8</encoding>
                </configuration>
            </plugin>
        </plugins>
    </build>

</project>

api module

在 api module 中的 pom.xml 文件添加 dubbo 、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 https://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <parent>
        <groupId>com.demo</groupId>
        <artifactId>nava</artifactId>
        <version>0.0.1-SNAPSHOT</version>
        <relativePath>../pom.xml</relativePath>
    </parent>
    <artifactId>nava-api</artifactId>
    <name>nava-api</name>
    <description>api 模块,对外提供的 API</description>
    <dependencies>
        <dependency>
            <groupId>io.grpc</groupId>
            <artifactId>grpc-netty</artifactId>
            <exclusions>
                <exclusion>
                    <groupId>io.netty</groupId>
                    <artifactId>netty-codec-http2</artifactId>
                </exclusion>
                <exclusion>
                    <groupId>io.netty</groupId>
                    <artifactId>netty-handler-proxy</artifactId>
                </exclusion>
            </exclusions>
        </dependency>
        <dependency>
            <groupId>io.grpc</groupId>
            <artifactId>grpc-netty-shaded</artifactId>
        </dependency>
        <dependency>
            <groupId>io.grpc</groupId>
            <artifactId>grpc-protobuf</artifactId>
        </dependency>
        <dependency>
            <groupId>io.grpc</groupId>
            <artifactId>grpc-stub</artifactId>
        </dependency>
        <dependency>
            <groupId>org.apache.dubbo</groupId>
            <artifactId>dubbo-common</artifactId>
        </dependency>

    </dependencies>

    <build>
        <plugins>
            <plugin>
                <groupId>kr.motd.maven</groupId>
                <artifactId>os-maven-plugin</artifactId>
                <version>1.7.1</version>
                <executions>
                    <execution>
                        <id>os-maven-plugin</id>
                        <phase>initialize</phase>
                        <goals>
                            <goal>detect</goal>
                        </goals>
                    </execution>
                </executions>
            </plugin>
            <plugin>
                <groupId>org.xolstice.maven.plugins</groupId>
                <artifactId>protobuf-maven-plugin</artifactId>
                <version>0.6.1</version>
                <configuration>
                    <protocArtifact>com.google.protobuf:protoc:3.7.1:exe:${os.detected.classifier}</protocArtifact>
                    <pluginId>grpc-java</pluginId>
                    <pluginArtifact>io.grpc:protoc-gen-grpc-java:${grpc.version}:exe:${os.detected.classifier}</pluginArtifact>
                    <protocPlugins>
                        <protocPlugin>
                            <id>dubbo-grpc</id>
                            <groupId>org.apache.dubbo</groupId>
                            <artifactId>dubbo-compiler</artifactId>
                            <version>0.0.1</version>
                            <mainClass>org.apache.dubbo.gen.grpc.DubboGrpcGenerator</mainClass>
                        </protocPlugin>
                    </protocPlugins>
                </configuration>
                <executions>
                    <execution>
                        <id>protobuf-maven-plugin</id>
                        <goals>
                            <goal>compile</goal>
                            <goal>compile-custom</goal>
                        </goals>
                    </execution>
                </executions>
            </plugin>
        </plugins>
    </build>

</project>

在main文件夹下面创建proto文件夹,以及 DemoService.proto 文件。
在这里插入图片描述

DemoService.proto

syntax = "proto3";

option java_multiple_files = true;
option java_package = "com.demo.nava";
option java_outer_classname = "DemoServiceProto";
option objc_class_prefix = "DSP";

// The greeting service definition.
service DemoService {
   
   
  // Sends a greeting
  rpc service (RequestData) returns (ResponseData) {
   
   }
}

// The request message containing the user's name.
message RequestData {
   
   
  string name = 1;
}

// The response message containing the greetings
message ResponseData {
   
   
  string message = 1;
}

service module

在 service module 中的 pom.xml 文件添加 api module 的依赖以及 dubbo 其他依赖。

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>com.demo</groupId>
        <artifactId>nava</artifactId>
        <version>0.0.1-SNAPSHOT</version>
        <relativePath>../pom.xml</relativePath>
    </parent>
    <artifactId>nava-service</artifactId>
    <name>nava-service</name>
    <description>service 模块,存放核心业务逻辑代码</description>
    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter</artifactId>
        </dependency>
        <dependency>
            <groupId>com.demo</groupId>
            <artifactId>nava-api</artifactId>
        </dependency>
        <dependency>
            <groupId>org.apache.dubbo</groupId>
            <artifactId>dubbo-registry-nacos</artifactId>
        </dependency>
        <dependency>
            <groupId>org.apache.dubbo</groupId>
            <artifactId>dubbo-spring-boot-starter</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>1.8</source>
                    <target>1.8</target>
                    <encoding>UTF-8</encoding>
                </configuration>
            </plugin>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
                <version>2.6.11</version>
                <configuration>
                    <mainClass>com.demo.nava.NavaApplication</mainClass>
                </configuration>
                <executions>
                    <execution>
                        <id>repackage</id>
                        <goals>
                            <goal>repackage</goal>
                        </goals>
                    </execution>
                </executions>
            </plugin>
        </plugins>
    </build>

</project>

application.properties 文件中添加 dubbo 相关配置

application.properties


# 设置dubbo传输协议
dubbo.protocol.name=grpc
dubbo.protocol.port=-1
# dubbo nacos注册中心说明 https://cn.dubbo.apache.org/zh-cn/overview/mannual/java-sdk/reference-manual/registry/nacos/
dubbo.registry.address: nacos://nacos:nacos@${
   
   nacos.address:127.0.0.1}:8848

在 SpringBoot 启动类添加 @EnableDubbo 注解

在这里插入图片描述

添加 DemoServiceImpl 实现类进行业务编码。

DemoServiceImpl.java

package com.demo.nava.service;

import com.demo.nava.DubboDemoServiceGrpc;
import com.demo.nava.RequestData;
import com.demo.nava.ResponseData;
import io.grpc.stub.StreamObserver;
import org.apache.dubbo.config.annotation.DubboService;

@DubboService
public class DemoServiceImpl extends DubboDemoServiceGrpc.DemoServiceImplBase implements DubboDemoServiceGrpc.IDemoService {
   
   

    @Override
    public void service(RequestData request, StreamObserver<ResponseData> responseObserver) {
   
   
        ResponseData reply = ResponseData.newBuilder().setMessage("Hello " + request.getName()).build();
        responseObserver.onNext(reply);
        responseObserver.onCompleted();
    }
}

注意事项

经过以上的步骤,一个简单的 SpringBoot 集成 Dubbo 启用 gRPC 协议的示例就完成了。这个时候直接启动项目是会报错的,因为protobuf相关的代码还没生成,我们需要对项目进行 maven install 以及 maven reload 操作。

maven install 的目的是为了生成protobuf相关代码,这个时候我们可以在 target 中看到

在这里插入图片描述

maven reload 的目的是为了更新加载 pom.xml 文件,从而将 api module 中生成的代码加载到 service module。

操作后就可以成功启动项目了。

区别

在项目启动成功后可以回头看下 Dubbo 支持的原生 gRPC 与原生 gRPC 在代码编写过程中的区别

  1. maven plugin 的区别,dubbo 在原先的基础上添加了 dubbo-grpc 的 plugin,目的是生成扩展的代码做到对 grpc 的支持。
    在这里插入图片描述
    对应生成的代码如下
    在这里插入图片描述
  1. service 实现区别,dubbo-grpc 的 plugin 生成了 dubbo 相关的 protobuf 的代码,所以在实现上有所区别。
    在这里插入图片描述

  2. RPC 调用区别,因为 grpc 接入了 dubbo 体系,所以使用 Dubbo 风格,基于接口的编程来定义和使用远程服务。
    在这里插入图片描述

相关文章
|
2月前
|
Java Maven Docker
gitlab-ci 集成 k3s 部署spring boot 应用
gitlab-ci 集成 k3s 部署spring boot 应用
|
7天前
|
Dubbo 安全 应用服务中间件
Apache Dubbo 正式发布 HTTP/3 版本 RPC 协议,弱网效率提升 6 倍
在 Apache Dubbo 3.3.0 版本之后,官方推出了全新升级的 Triple X 协议,全面支持 HTTP/1、HTTP/2 和 HTTP/3 协议。本文将围绕 Triple 协议对 HTTP/3 的支持进行详细阐述,包括其设计目标、实际应用案例、性能测试结果以及源码架构分析等内容。
|
21天前
|
XML Java 数据库连接
SpringBoot集成Flowable:打造强大的工作流管理系统
在企业级应用开发中,工作流管理是一个核心组件,它能够帮助我们定义、执行和管理业务流程。Flowable是一个开源的工作流和业务流程管理(BPM)平台,它提供了强大的工作流引擎和建模工具。结合SpringBoot,我们可以快速构建一个高效、灵活的工作流管理系统。本文将探讨如何将Flowable集成到SpringBoot应用中,并展示其强大的功能。
71 1
|
1月前
|
JSON Java API
springboot集成ElasticSearch使用completion实现补全功能
springboot集成ElasticSearch使用completion实现补全功能
35 1
|
21天前
|
XML 存储 Java
SpringBoot集成Flowable:构建强大的工作流引擎
在企业级应用开发中,工作流管理是核心功能之一。Flowable是一个开源的工作流引擎,它提供了BPMN 2.0规范的实现,并且与SpringBoot框架完美集成。本文将探讨如何使用SpringBoot和Flowable构建一个强大的工作流引擎,并分享一些实践技巧。
58 0
|
2月前
|
前端开发 Java 程序员
springboot 学习十五:Spring Boot 优雅的集成Swagger2、Knife4j
这篇文章是关于如何在Spring Boot项目中集成Swagger2和Knife4j来生成和美化API接口文档的详细教程。
114 1
|
2月前
|
存储 前端开发 Java
Spring Boot 集成 MinIO 与 KKFile 实现文件预览功能
本文详细介绍如何在Spring Boot项目中集成MinIO对象存储系统与KKFileView文件预览工具,实现文件上传及在线预览功能。首先搭建MinIO服务器,并在Spring Boot中配置MinIO SDK进行文件管理;接着通过KKFileView提供文件预览服务,最终实现文档管理系统的高效文件处理能力。
318 11
|
3月前
|
XML Java 关系型数据库
springboot 集成 mybatis-plus 代码生成器
本文介绍了如何在Spring Boot项目中集成MyBatis-Plus代码生成器,包括导入相关依赖坐标、配置快速代码生成器以及自定义代码生成器模板的步骤和代码示例,旨在提高开发效率,快速生成Entity、Mapper、Mapper XML、Service、Controller等代码。
springboot 集成 mybatis-plus 代码生成器
|
3月前
|
Java Spring
springboot 集成 swagger 2.x 和 3.0 以及 Failed to start bean ‘documentationPluginsBootstrapper‘问题的解决
本文介绍了如何在Spring Boot项目中集成Swagger 2.x和3.0版本,并提供了解决Swagger在Spring Boot中启动失败问题“Failed to start bean ‘documentationPluginsBootstrapper’; nested exception is java.lang.NullPointerEx”的方法,包括配置yml文件和Spring Boot版本的降级。
springboot 集成 swagger 2.x 和 3.0 以及 Failed to start bean ‘documentationPluginsBootstrapper‘问题的解决
|
2月前
|
Java Spring
springboot 学习十一:Spring Boot 优雅的集成 Lombok
这篇文章是关于如何在Spring Boot项目中集成Lombok,以简化JavaBean的编写,避免冗余代码,并提供了相关的配置步骤和常用注解的介绍。
105 0