本文记录下SpringBoot集成Dubbo启用gRPC协议,以及与原生 gRPC 在代码编写过程中的区别。
下面还有投票,帮忙投个票
Dubbo 在 2.7.5 版本开始支持原生 gRPC 协议,对于计划使用 HTTP/2 通信或者期望 gRPC 协议支持服务治理能力的,都可以考虑接入 Dubbo 体系启用 gRPC 协议。
由于官网给的 代码示例 是基于 spring,现在基本上都是基于SpringBoot开发,所以本文提供一下 SpringBoot 的代码示例。
此外还会简单说明 Dubbo 支持的原生 gRPC 协议与原生 gRPC 协议在代码开发时的区别。
如果对gRPC协议不了解的,后续文章会有更新,请持续关注。
这样的项目结构可以将服务的声明和实现隔离开,如果有 client 调用,直接添加api module 的依赖即可。
项目结构确定好后需要做三件事
详细代码如下:
父工程中的 pom.xml 文件添加 grpc 和 dubbo 的 BOM。
pom.xml
<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.0modelVersion>
<groupId>com.demogroupId>
<artifactId>navaartifactId>
<version>0.0.1-SNAPSHOTversion>
<packaging>pompackaging>
<name>navaname>
<description>Demo project for Spring Bootdescription>
<properties>
<java.version>1.8java.version>
<project.build.sourceEncoding>UTF-8project.build.sourceEncoding>
<project.reporting.outputEncoding>UTF-8project.reporting.outputEncoding>
<dubbo.version>3.1.7dubbo.version>
<grpc.version>1.44.1grpc.version>
<spring-boot.version>2.6.11spring-boot.version>
properties>
<modules>
<module>nava-apimodule>
<module>nava-servicemodule>
modules>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>io.grpcgroupId>
<artifactId>grpc-bomartifactId>
<version>${grpc.version}version>
<type>pomtype>
<scope>importscope>
dependency>
<dependency>
<groupId>org.springframework.bootgroupId>
<artifactId>spring-boot-dependenciesartifactId>
<version>${spring-boot.version}version>
<type>pomtype>
<scope>importscope>
dependency>
<dependency>
<groupId>org.apache.dubbogroupId>
<artifactId>dubbo-bomartifactId>
<version>${dubbo.version}version>
<type>pomtype>
<scope>importscope>
dependency>
<dependency>
<groupId>com.demogroupId>
<artifactId>nava-apiartifactId>
<version>0.0.1-SNAPSHOTversion>
dependency>
<dependency>
<groupId>com.demogroupId>
<artifactId>nava-serviceartifactId>
<version>0.0.1-SNAPSHOTversion>
dependency>
dependencies>
dependencyManagement>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.pluginsgroupId>
<artifactId>maven-compiler-pluginartifactId>
<version>3.8.1version>
<configuration>
<source>1.8source>
<target>1.8target>
<encoding>UTF-8encoding>
configuration>
plugin>
plugins>
build>
project>
在 api module 中的 pom.xml 文件添加 dubbo 、gRPC 所需依赖、插件。
pom.xml
<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.0modelVersion>
<parent>
<groupId>com.demogroupId>
<artifactId>navaartifactId>
<version>0.0.1-SNAPSHOTversion>
<relativePath>../pom.xmlrelativePath>
parent>
<artifactId>nava-apiartifactId>
<name>nava-apiname>
<description>api 模块,对外提供的 APIdescription>
<dependencies>
<dependency>
<groupId>io.grpcgroupId>
<artifactId>grpc-nettyartifactId>
<exclusions>
<exclusion>
<groupId>io.nettygroupId>
<artifactId>netty-codec-http2artifactId>
exclusion>
<exclusion>
<groupId>io.nettygroupId>
<artifactId>netty-handler-proxyartifactId>
exclusion>
exclusions>
dependency>
<dependency>
<groupId>io.grpcgroupId>
<artifactId>grpc-netty-shadedartifactId>
dependency>
<dependency>
<groupId>io.grpcgroupId>
<artifactId>grpc-protobufartifactId>
dependency>
<dependency>
<groupId>io.grpcgroupId>
<artifactId>grpc-stubartifactId>
dependency>
<dependency>
<groupId>org.apache.dubbogroupId>
<artifactId>dubbo-commonartifactId>
dependency>
dependencies>
<build>
<plugins>
<plugin>
<groupId>kr.motd.mavengroupId>
<artifactId>os-maven-pluginartifactId>
<version>1.7.1version>
<executions>
<execution>
<id>os-maven-pluginid>
<phase>initializephase>
<goals>
<goal>detectgoal>
goals>
execution>
executions>
plugin>
<plugin>
<groupId>org.xolstice.maven.pluginsgroupId>
<artifactId>protobuf-maven-pluginartifactId>
<version>0.6.1version>
<configuration>
<protocArtifact>com.google.protobuf:protoc:3.7.1:exe:${os.detected.classifier}protocArtifact>
<pluginId>grpc-javapluginId>
<pluginArtifact>io.grpc:protoc-gen-grpc-java:${grpc.version}:exe:${os.detected.classifier}pluginArtifact>
<protocPlugins>
<protocPlugin>
<id>dubbo-grpcid>
<groupId>org.apache.dubbogroupId>
<artifactId>dubbo-compilerartifactId>
<version>0.0.1version>
<mainClass>org.apache.dubbo.gen.grpc.DubboGrpcGeneratormainClass>
protocPlugin>
protocPlugins>
configuration>
<executions>
<execution>
<id>protobuf-maven-pluginid>
<goals>
<goal>compilegoal>
<goal>compile-customgoal>
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 中的 pom.xml 文件添加 api module 的依赖以及 dubbo 其他依赖。
pom.xml
<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.0modelVersion>
<parent>
<groupId>com.demogroupId>
<artifactId>navaartifactId>
<version>0.0.1-SNAPSHOTversion>
<relativePath>../pom.xmlrelativePath>
parent>
<artifactId>nava-serviceartifactId>
<name>nava-servicename>
<description>service 模块,存放核心业务逻辑代码description>
<dependencies>
<dependency>
<groupId>org.springframework.bootgroupId>
<artifactId>spring-boot-starterartifactId>
dependency>
<dependency>
<groupId>com.demogroupId>
<artifactId>nava-apiartifactId>
dependency>
<dependency>
<groupId>org.apache.dubbogroupId>
<artifactId>dubbo-registry-nacosartifactId>
dependency>
<dependency>
<groupId>org.apache.dubbogroupId>
<artifactId>dubbo-spring-boot-starterartifactId>
dependency>
<dependency>
<groupId>org.springframework.bootgroupId>
<artifactId>spring-boot-starter-testartifactId>
<scope>testscope>
dependency>
dependencies>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.pluginsgroupId>
<artifactId>maven-compiler-pluginartifactId>
<version>3.8.1version>
<configuration>
<source>1.8source>
<target>1.8target>
<encoding>UTF-8encoding>
configuration>
plugin>
<plugin>
<groupId>org.springframework.bootgroupId>
<artifactId>spring-boot-maven-pluginartifactId>
<version>2.6.11version>
<configuration>
<mainClass>com.demo.nava.NavaApplicationmainClass>
configuration>
<executions>
<execution>
<id>repackageid>
<goals>
<goal>repackagegoal>
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 在代码编写过程中的区别