基于Protobuf协议的Dubbo与SpringBoot的结合

2023-10-26


这里使用Protobuf作为IDL 定义Dubbo服务,并于SpringBoot相结合,搭建最原始的服务提供及消费模型。基于dubbo2.7.13,注册中心使用zookeeper。

工程概况

dubbo-provider$ tree -L 1 .
.
├── dubbo-provider-api
├── dubbo-provider-service
├── dubbo-provider-web
└── pom.xml

dubbo-consumer$ tree -L 1 .
.
├── dubbo-consumer-api
├── dubbo-consumer-service
├── dubbo-consumer-web
└── pom.xml

这里新建了两个SpringBoot项目,dubbo-provider用于提供对外服务,其中 dubbo-provider-api 用于提供api,会将其独立打包发布,用于第三方调用(如dubbo-consumer)。dubbo-consumer会远程调用dubbo-provider提供的服务。
两个项目中分别有3个子项组成,api仅仅用于定义对外提供服务接口(服务内部的接口不在此定义),service依赖api的接口,并给予具体的实现,而web则负责调用实现,对外提供服务。

父pom

先给出工程根目录下pom文件的内容,这个父pom文件主要用于统一管理一些包的依赖

<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<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>
    <groupId>com.demo.dubbo.provider</groupId>
    <artifactId>dubbo-provider</artifactId>
    <version>1.0-SNAPSHOT</version>
    <packaging>pom</packaging>

    <properties>
        <maven.compiler.encoding>UTF-8</maven.compiler.encoding>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        <dubbo.version>2.7.13</dubbo.version>
        <grpc.version>1.40.1</grpc.version>
        <dubbo.compiler.version>0.0.2</dubbo.compiler.version>
        <maven-compiler-plugin.version>3.7.0</maven-compiler-plugin.version>
    </properties>

    <dependencies>
        ...
    </dependencies>
    <dependencyManagement>
        <dependencies>

            <dependency>
                <groupId>org.apache.dubbo</groupId>
                <artifactId>dubbo-spring-boot-starter</artifactId>
                <version>${dubbo.version}</version>
            </dependency>
        
            <dependency>
                <groupId>org.apache.dubbo</groupId>
                <artifactId>dubbo-dependencies-zookeeper</artifactId>
                <version>${dubbo.version}</version>
            </dependency>
            <dependency>
                <groupId>org.apache.dubbo</groupId>
                <artifactId>dubbo-serialization-protobuf</artifactId>
                <version>${dubbo.version}</version>
            </dependency>

        </dependencies>
    </dependencyManagement>
    <profiles>
        <profile>
            ...
        </profile>
    </profiles>
    <build>
        <plugins>
            ...
        </plugins>
    </build>
    <distributionManagement>
        <repository>
            ...
        </repository>
    </distributionManagement>
    <modules>
        <module>dubbo-provider-api</module>
        <module>dubbo-provider-service</module>
        <module>dubbo-provider-web</module>
    </modules>
</project>

dubbo-provider

通过proto3定义服务

dubbo-provider-api的结构如下,注意这里的service目录下的文件都是根据proto协议自动生成的,请不要修改它。

dubbo-provider/dubbo-provider-api$ ll
总用量 20
drwxrwxr-x  4 mi mi 4096 1月  14 16:34 ./
drwxrwxr-x 13 mi mi 4096 1月  13 09:32 ../
-rw-rw-r--  1 mi mi 2802 1月  14 16:34 pom.xml
drwxrwxr-x  3 mi mi 4096 1月  11 17:49 src/
drwxrwxr-x  8 mi mi 4096 1月  14 16:35 target/
dubbo-provider/dubbo-provider-api$ tree .
.
├── pom.xml
├── src
│ └── main
│     ├── java
│     │ └── com
│     │     └── demo
│     │         └── dubbo
│     │             └── provider
│     │                 └── api
│     │                     └── service
│     │                         ├── DemoServiceDubbo.java
│     │                         ├── DemoService.java
│     │                         ├── DemoServiceProto.java
│     │                         ├── HelloReply.java
│     │                         ├── HelloReplyOrBuilder.java
│     │                         ├── HelloRequest.java
│     │                         └── HelloRequestOrBuilder.java
│     │                        
│     └── proto
│         └── DemoService.proto
└── target...

DemoService.proto定义如下:

syntax = "proto3";

option java_multiple_files = true;
option java_package = "com.demo.dubbo.provider.api.service";
option java_outer_classname = "DemoServiceProto";
option objc_class_prefix = "DEMOSRV";

package demoservice;

// The demo service definition.
service DemoService {
  rpc SayHello (HelloRequest) returns (HelloReply) {}
}

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

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

这里通过message关键字定义了请求和响应的内容格式,通过service关键字定义服务的接口。

打包发布服务

借助 protobuf-maven-plugin 编译proto文件,并将生成的文件放到源码目录下,便于之后可以将dubbo-provider-api进行打包发布。

<?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>com.demo.dubbo.provider</groupId>
		<artifactId>dubbo-provider</artifactId>
		<version>1.0-SNAPSHOT</version>
	</parent>
	<artifactId>dubbo-provider-api</artifactId>

	<dependencies>
		<dependency>
			<groupId>org.apache.dubbo</groupId>
			<artifactId>dubbo-serialization-protobuf</artifactId>
		</dependency>
	</dependencies>

	<build>
		<extensions>
			<extension>
				<groupId>kr.motd.maven</groupId>
				<artifactId>os-maven-plugin</artifactId>
				<version>1.6.1</version>
			</extension>
		</extensions>
		<plugins>
			<plugin>
				<groupId>org.xolstice.maven.plugins</groupId>
				<artifactId>protobuf-maven-plugin</artifactId>
				<version>0.5.1</version>
				<configuration>
					<protocArtifact>com.google.protobuf:protoc:3.7.1:exe:${os.detected.classifier}</protocArtifact>
					<outputDirectory>src/main/java</outputDirectory>
					<clearOutputDirectory>false</clearOutputDirectory>
					<protocPlugins>
						<protocPlugin>
							<id>dubbo</id>
							<groupId>org.apache.dubbo</groupId>
							<artifactId>dubbo-compiler</artifactId>
							<version>${dubbo.compiler.version}</version>
							<mainClass>org.apache.dubbo.gen.dubbo.Dubbo3Generator</mainClass>
						</protocPlugin>
					</protocPlugins>
				</configuration>
				<executions>
					<execution>
						<goals>
							<goal>compile</goal>
							<goal>test-compile</goal>
						</goals>
					</execution>
				</executions>
			</plugin>
			<plugin>
				<groupId>org.codehaus.mojo</groupId>
				<artifactId>build-helper-maven-plugin</artifactId>
				<executions>
					<execution>
						<phase>generate-sources</phase>
						<goals>
							<goal>add-source</goal>
						</goals>
						<configuration>
							<sources>
								<source>src/main/java</source>
							</sources>
						</configuration>
					</execution>
				</executions>
			</plugin>
			<plugin>
				<groupId>org.apache.maven.plugins</groupId>
				<artifactId>maven-compiler-plugin</artifactId>
				<version>${maven-compiler-plugin.version}</version>
				<configuration>
					<source>1.8</source>
					<target>1.8</target>
				</configuration>
			</plugin>
		</plugins>
	</build>
</project>

dubbo-provider-service实现服务

dubbo-provider-service将实现dubbo-provider-api中的接口。

<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>com.demo.dubbo.provider</groupId>
        <artifactId>dubbo-provider</artifactId>
        <version>1.0-SNAPSHOT</version>
    </parent>
    <artifactId>dubbo-provider-service</artifactId>
    <dependencies>
        <dependency>
            <groupId>com.demo.dubbo.provider</groupId>
            <artifactId>dubbo-provider-api</artifactId>
        </dependency>
    </dependencies>
</project>
package com.demo.dubbo.provider.service;

import com.demo.dubbo.provider.api.service.DemoService;
import com.demo.dubbo.provider.api.service.HelloReply;
import com.demo.dubbo.provider.api.service.HelloRequest;
import org.apache.dubbo.config.annotation.DubboService;
import org.apache.dubbo.rpc.RpcContext;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;

import java.util.concurrent.CompletableFuture;

@DubboService
@Component
public class DemoServiceImpl implements DemoService {
    private static final Logger logger = LoggerFactory.getLogger(DemoServiceImpl.class);

    @Override
    public HelloReply sayHello(HelloRequest request) {
        logger.info("Hello " + request.getName() + ", request from consumer: " + RpcContext.getContext().getRemoteAddress());
        HelloReply response = HelloReply.newBuilder()
                .setMessage("Hello " + request.getName() + ", response from provider: "
                        + RpcContext.getContext().getLocalAddress())
                .build();
        logger.info("response:{}", response);
        return response;
    }

    @Override
    public CompletableFuture<HelloReply> sayHelloAsync(HelloRequest request) {
        return CompletableFuture.completedFuture(sayHello(request));
    }
}

dubbo-provider-web提供服务

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.dubbo.provider</groupId>
		<artifactId>dubbo-provider</artifactId>
		<version>1.0-SNAPSHOT</version>
	</parent>
	<artifactId>dubbo-provider-web</artifactId>
	<packaging>jar</packaging>
	<name>dubbo-provider-web</name>
	<description>dubbo-provider-web project for Spring Boot</description>

	<properties>
		<springboot.version>2.4.0</springboot.version>
		<java.version>1.8</java.version>
	</properties>

	<dependencies>
		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-web</artifactId>
			<version>${springboot.version}</version>
		</dependency>

		<dependency>
			<groupId>org.apache.dubbo</groupId>
			<artifactId>dubbo-spring-boot-starter</artifactId>
		</dependency>

		<dependency>
			<groupId>org.apache.dubbo</groupId>
			<artifactId>dubbo-dependencies-zookeeper</artifactId>
			<version>2.7.13</version>
			<type>pom</type>
		</dependency>

		<dependency>
			<groupId>com.demo.dubbo.provider</groupId>
			<artifactId>dubbo-provider-service</artifactId>
			<version>1.0-SNAPSHOT</version>
		</dependency>

	</dependencies>
	<build>
		<finalName>dubbo-provider-web</finalName>
		<resources>
			<resource>
				<directory>src/main/resources</directory>
				<filtering>true</filtering>
				<includes>
					<include>**/application.properties</include>
					<include>**/logback.xml</include>
				</includes>
			</resource>
		</resources>
		<plugins>
			<plugin>
				<groupId>org.springframework.boot</groupId>
				<artifactId>spring-boot-maven-plugin</artifactId>
				<version>${springboot.version}</version>
				<executions>
					<execution>
						<goals>
							<goal>repackage</goal>
						</goals>
					</execution>
				</executions>
			</plugin>
		</plugins>
	</build>
</project>

application.properties

dubbo.application.name=dubbo-provider-provider
dubbo.registry.address=zookeeper://127.0.0.1:2181
dubbo.protocol.name=dubbo
dubbo.protocol.serialization=protobuf

注意:dubbo.protocol.serialization=protobuf一定要添加,否则会用dubbo默认的序列化协议(Hessian2),将导致序列化失败,无法将参数写入请求体中。

通过EnableDubbo实现自动装配dubbo的配置

package com.demo.dubbo.provider.web;

import org.apache.dubbo.config.spring.context.annotation.EnableDubbo;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

@SpringBootApplication(scanBasePackages = "com.demo.dubbo.provider")
@EnableDubbo(scanBasePackages = "com.demo.dubbo.provider")
public class ProviderBootWebApplication {

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

dubbo-consumer

dubbo-consumer-api

dubbo-consumer-api这里无需定义,因为我们不打算对外提供服务。

dubbo-consumer-service

dubbo-consumer-service将依赖dubbo-provider-api,以便直接使用其中服务定义。

<?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>com.demo.dubbo.consumer</groupId>
        <artifactId>dubbo-consumer</artifactId>
        <version>1.0-SNAPSHOT</version>
    </parent>
    <artifactId>dubbo-consumer-service</artifactId>

    <dependencies>
        
        <dependency>
            <groupId>com.demo.dubbo.provider</groupId>
            <artifactId>dubbo-provider-api</artifactId>
            <version>1.0-SNAPSHOT</version>
        </dependency>

        <dependency>
            <groupId>org.apache.dubbo</groupId>
            <artifactId>dubbo-common</artifactId>
            <version>2.7.13</version>
            <scope>compile</scope>
        </dependency>
    </dependencies>

</project>
package com.demo.dubbo.consumer.service;

import com.demo.dubbo.provider.api.service.DemoService;
import com.demo.dubbo.provider.api.service.HelloReply;
import com.demo.dubbo.provider.api.service.HelloRequest;
import lombok.extern.slf4j.Slf4j;
import org.apache.dubbo.config.annotation.DubboReference;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

@Slf4j
@Service
public class ConsumerService {

    @DubboReference(version = "*", loadbalance = "random")
    private DemoService demoService;

    public String hello(String name) {
        log.info("receiver:{}", name);
        HelloRequest request = HelloRequest.newBuilder().setName(name).build();
        HelloReply response = demoService.sayHello(request);
        log.info("response:{}", response);

        return response.getMessage();
    }
}

通过DubboReference引用dubbo-provider-api提供的服务。关于DubboReference注解的详细内容,在此不展开详述。在此,version用于版本控制:当一个接口实现,出现不兼容升级时,可以用版本号过渡,版本号不同的服务相互间不引用。loadbalance用于负载均衡,常见的算法有random,roundRobin,leastActive,consistentHash。

dubbo-consumer-web提供服务

pom文件参考 dubbo-provider-web.
application.properties

dubbo.application.name=dubbo-consumer
dubbo.registry.address=zookeeper://127.0.0.1:2181
dubbo.protocol.name=dubbo
dubbo.protocol.serialization=protobuf

注意:dubbo.protocol.serialization=protobuf一定要添加,否则会用dubbo默认的序列化协议,将导致序列化失败,无法将请求参数序列化成功。

package com.demo.dubbo.consumer.web;

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

@SpringBootApplication(scanBasePackages = "com.demo.dubbo")
public class ConsumerBootWebApplication {

	public static void main(String[] args) {
		SpringApplication.run(ConsumerBootWebApplication.class, args);
	}
}
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

基于Protobuf协议的Dubbo与SpringBoot的结合 的相关文章

随机推荐

  • Callable 和 Future

    Callable 和 Future 是 Java 并发编程中用于处理多线程任务的两个关键接口 它们通常与线程池一起使用 以实现异步任务执行和获取结果的功能 Callable Callable 是一个泛型接口 它定义了一个带有返回值的任务 与
  • 多线程爬虫的实现----threading库的使用

    1 作爬虫的时候为了提升抓取的速度 这个时候就需要开启多个线程同时抓取数据 今天就分享一下如何使用Python中的threading库实现多线程抓取数据 from shop import ShopSpider import threadin
  • 微服务框架相关 OpenFeign 源码

    目录 一 基础 二 初始化注册 三 FeignClient 自动配置 四 FeignClient 创建 五 网络请求的发出 六 负载均衡 SpringCloud Loadbalancer 一 基础 使用 OpenFeign 流程 项目中引入
  • 2如何识别操作系统_信创产业成为风口,如何“迁移”值得研究(二)

    在上一讲 信创产业成为风口 如何 迁移 值得研究 中 我们分析了什么是 信创 以及数据迁移在信创过程中的重要意义及其基本要求 本次文章中我们将继续分析 信创实践过程中数据迁移的难点及其解决之道 1难点1 迁移场景复杂 在信创实践过程中 随着
  • html搜索栏热搜效果,CSS3实战开发:百度新闻热搜词特效实战开发_html/css_WEB-ITnose...

    各位网友 今天这篇文章 我将手把手带领大家开发百度新闻首页的 新闻热搜词 特效 在这个特效中应用的知识点都很基础 如果你对这些还不清楚 可以关注我以前写的详细教程 今天讲这个案例 也是希望告诉大家 在开发一个特效的时候 请不要将问题复杂化
  • valn的基础配置

    vlan作业 1 交换机进行vlan配置 lsw1 lsw2 2 进行单臂路由的配置 3 DHCP配置 地址池的配置 端口启动
  • LR-ASPP论文

    论文地址 https arxiv org abs 1905 02244 摘要 我们提出了基于互补搜索技术的组合以及一个新颖的架构设计的下一代移动网络 MobileNetV3通过结合NetAdapt算法补充的硬件网络架构搜索 NAS 调整到移
  • 配置JAVA环境变量

    一 自行安装JDK 位置默认C盘 JDK全称是Java Development Kit 是整个Java的核心 包括了Java运行环境 Java工具和Java基础类库 JDK 是整个Java的核心 包括了Java运行环境 Java工具和Jav
  • 一文读懂 QUIC 协议:更快、更稳、更高效的网络通信

    作者 李龙彦 来源 infoQ 你是否也有这样的困扰 打开 APP 巨耗时 刷剧一直在缓冲 追热搜打不开页面 信号稍微差点就直接加载失败 如果有一个协议能让你的上网速度 在不需要任何修改的情况下就能提升 20 特别是网络差的环境下能够提升
  • 万得Wind量化与东方财富Choice量化接口使用

    接口需要付费 这里接口的付费和配置就不展开了 wind相对容易配置 直接用软件就可以点击并配置 东财请参考 Mac使用Python接入东方财富量化接口Choice 调试与获取数据 但有一点需要注意 wind使用量化接口的时候wind终端需要
  • 王炸功能ChatGPT 联网插件功能放开,视频文章一键变思维导图

    就在上周5月13日 Open AI 发文称 我们将在下周向所有ChatGPT Plus 用户开放联网功能和众多插件 这意味着什么 首先联网功能将使得ChatGPT不再局限于回答2021年9月之前的信息 能直接联网查询最新消息 而插件功能就可
  • BIOS启动过程详解

    BIOS 工作原理 最近几天在看 UNIX 操作系统设计 突然想到计算机是如何启动的呢 那就得从 BIOS 说起 其实这个冬冬早已是 n 多人写过的了 今天就以自己的理解来写写 权当一个学习笔记 一 预备知识 很多人将 BIOS 与 CMO
  • 19.3剪裁

    1 在固定管线中 裁剪是在世界坐标系中 2 在可编程管线中 裁剪是在规格化坐标系中 步骤 1 按照法向量和空间点定义裁剪平面 并归一化 2 根据世界观察投影变换矩阵相乘 求逆转置 即为需要的变换矩阵 3 变换矩阵与裁剪平面变换后就是需要的裁
  • numpy模块(2)

    1 利用布尔值来取元素 import numpy as np mask np array 1 0 1 dtype bool 1表示取对应的元素 0表示不取 arr np array 1 2 3 4 5 6 7 8 9 print arr m
  • Hadoop学习心得---二

    大数据运算解决方案MapReduce Hadoop的分布式计算模型MapReduce 最早是Google提出的 主要用于搜索领域 解决海量数据的计算问题 MapReduce有两个阶段组成 Map和Reduce 用户只需实现map 和redu
  • Three.js(学习)

    在vue项目中使用Three js的流程 1 首先利用npm安装Q three js 具体操作代码如下 npm install three 2 接下来利用npm安装轨道控件插件 npm install three orbit control
  • 表、栈和队列

    表 栈和队列 表 增强的for循环 List
  • DM6437 C64X+ EDMA 疑惑总结记录

    总结一下DM6437中的EDMA的使用出现的问题 方便以后再开发定位问题 1 EDMA Link 和 Chain的区别 link实现了DMA的自动重加载 非静态模式 需要两个param chain是不更新param set表 直接event
  • qt界面叠加视频OSD双层显示

    最终代码存放于 http download csdn net detail lzh445096 8849147 本人负责的是UI界面 提供给底层应用程序接口函数 此接口函数功能为向指定路径的文件中写入命令字符 应用程序去到该文件中读取到相应
  • 基于Protobuf协议的Dubbo与SpringBoot的结合

    文章目录 工程概况 父pom dubbo provider 通过proto3定义服务 打包发布服务 dubbo provider service实现服务 dubbo provider web提供服务 dubbo consumer dubbo