从一个Demo说起Dubbo3

news2025/1/23 7:26:36

简介

2017年的9月份,阿里宣布重启Dubbo的开发维护,并且后续又将Dubbo捐献给了Apache,经过多年的发展已经发布到3.X版本了,Dubbo重启维护之后是否有值得我们期待的功能呢,下面就来看看吧。

Apache Dubbo 是一款微服务框架,为大规模微服务实践提供高性能 RPC 通信、流量治理、可观测性等解决方案,涵盖 Java、Golang 等多种语言 SDK 实现。

Dubbo3在官网首页的介绍中是这样描述的:Dubbo3是下一代云原生微服务框架 - 3.0 版本的正式发布,标志着 Apache Dubbo 正式进入云原生时代。3.0 在通信协议、服务发现、部署架构、服务治理上都对云原生基础设施进行了全面适配, 提供了Triple、应用级服务发现、Dubbo Mesh等核心特性。

可以看到Dubbo3不再仅仅是一个简单的RPC通信框架了,在云原生实践中Dubbo3逐渐将通用业务下沉与业务逻辑剥离,实现Dubbo Mesh(Service Mesh翻译为“服务网格” Dubbo Mesh暂时就翻译为“Dubbo服务网格吧”)功能,如果Dubbo能让这个Mesh功能实现的简单易用,性能高效那微服务项目的开发大家就可以只关注CRUD了。

通过官方社区了解到的资料,Dubbo3 已被阿里巴巴、饿了么、钉钉、工商银行、小米等在生产环境广泛采用。Dubbo3从内到外的推广已经从理论转到了实践,不过是否比原先的Dubbo2好用呢,下面可以从架构到示例来看下。

架构

Dubbo3部署架构

threecenters

可以看到Dubbo3的架构图里面新包含了三大中心的概念:

  • 注册中心: 协调 Consumer 与 Provider 之间的地址注册与发现
  • 配置中心: 存储 Dubbo 启动阶段的全局配置,保证配置的跨环境共享与全局一致性,负责服务治理规则(路由规则、动态配置等)的存储与推送。
  • 元数据中心: 接收 Provider 上报的服务接口元数据,为 Admin 等控制台提供运维能力(如服务测试、接口文档等),作为服务发现机制的补充,提供额外的接口/方法级别配置信息的同步能力,相当于注册中心的额外扩展

可以看到这里比较新的概念元数据中心做的事情是用来存储服务接口的元数据,在Dubbo2中服务接口数据与应用数据都是存储在注册中心了,这里将接口元数据抽离到元数据中心,让注册中心专注于应用级服务发现。

应用级服务发现模型

//imgs/v3/concepts/servicediscovery_mem.png

应用级服务发现模型的粒度是以应用单元来进行服务发现的,Dubbo2中的接口级发现不仅仅会造成注册中心数据的膨胀,同时也无法让Dubbo应用于其他微服务框架的应用比如SpringCloud实现互联互通,在打通了地址发现之后,应用级服务发现使得用户探索用 Dubbo 连接异构的微服务体系成为了一种可能。

另外应用级服务发现模型会将元数据信息的获取下沉到一个RPC请求之中,这个让服务通知得以高效,如下图:

image-20230106083609338

Dubbo3的优化不仅仅是这个服务发现模型,不过接口级服务发现模型到应用级服务发现模型的转变是升级过程中最值得关注的其中一个地方。

Dubbo3也有一些其他亮点的功能比如新增基于 HTTP/2 之上定义的下一代 RPC 通信协议Triple 协议,Mesh 解决方案等,感兴趣可以自行去官网查看,这里主要基于一个服务提供者的Demo示例来看下如何使用Dubbo3。

服务提供者的Demo

为了更方便了解原理,我们先来编写一个Demo,从例子中来看源码实现:

启动Zookeeper

为了Demo可以正常启动,需要我们先在本地启动一个Zookeeper,如下命令所示(Zookeeper可以在官网下载下载之后载conf下新建配置文件zoo.cfg):

mac@MacdeMacBook-Pro apache-zookeeper-3.6.3-bin % ./bin/zkServer.sh start
ZooKeeper JMX enabled by default
Using config: /Users/mac/Desktop/computer/A/env/apache-zookeeper-3.6.3-bin/bin/../conf/zoo.cfg
Starting zookeeper ... STARTED
mac@MacdeMacBook-Pro apache-zookeeper-3.6.3-bin % 

前面我们介绍了Dubbo3需要三大中心,这里我们让配置中心,元数据中心和注册中心都使用我们启动的Zookeeper,这样相对方便一些。

依赖引入

下面就直接来贴一些核心的依赖内容

<dependencyManagement>
        <dependencies>
            <dependency>
                <groupId>org.apache.dubbo</groupId>
                <artifactId>dubbo-bom</artifactId>
                <version>3.2.0-beta.3</version>
                <type>pom</type>
                <scope>import</scope>
            </dependency>
        </dependencies>
</dependencyManagement>
 <dependencies>
        <!-- dubbo starter -->
        <dependency>
            <groupId>org.apache.dubbo</groupId>
            <artifactId>dubbo-spring-boot-starter</artifactId>
        </dependency>
        <!-- dubbo Zookeeper注册中心扩展 -->
   			 <dependency>
            <groupId>org.apache.dubbo</groupId>
            <artifactId>dubbo-dependencies-zookeeper</artifactId>
            <type>pom</type>
        </dependency>
      	 <!-- dubbo  开启一些可观测性功能依赖 -->
        <dependency>
            <groupId>org.apache.dubbo</groupId>
            <artifactId>dubbo-spring-boot-actuator</artifactId>
        </dependency>
</dependencies>

服务提供者

接下来给大家贴一下示例源码,这个源码来源于Dubbo源码目录的 dubbo-demo/dubbo-demo-api 目录下面的dubbo-demo-api-provider子项目,这里我做了删减,方便看核心代码:
首先我们定义一个服务接口如下所示:

import java.util.concurrent.CompletableFuture;
public interface DemoService {
    /**
     * 同步处理的服务方法
     * @param name
     * @return
     */
    String sayHello(String name);

    /**
     * 用于异步处理的服务方法
     * @param name
     * @return
     */
    default CompletableFuture<String> sayHelloAsync(String name) {
        return CompletableFuture.completedFuture(sayHello(name));
    }
}

服务接口对应的实现类如下:

import org.apache.dubbo.rpc.RpcContext;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.util.concurrent.CompletableFuture;

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

    @Override
    public String sayHello(String name) {
        logger.info("Hello " + name + ", request from consumer: " + RpcContext.getServiceContext().getRemoteAddress());
        return "Hello " + name + ", response from provider: " + RpcContext.getServiceContext().getLocalAddress();
    }

    @Override
    public CompletableFuture<String> sayHelloAsync(String name) {
        return null;
    }

}

启用服务提供者

有了服务接口之后我们来启用服务,启用服务的源码如下:

import org.apache.dubbo.common.constants.CommonConstants;
import org.apache.dubbo.config.ApplicationConfig;
import org.apache.dubbo.config.MetadataReportConfig;
import org.apache.dubbo.config.ProtocolConfig;
import org.apache.dubbo.config.RegistryConfig;
import org.apache.dubbo.config.ServiceConfig;
import org.apache.dubbo.config.bootstrap.DubboBootstrap;
import org.apache.dubbo.demo.DemoService;

public class Application {
    public static void main(String[] args) throws Exception {
            startWithBootstrap();
    }
    private static void startWithBootstrap() {
        //创建服务配置
        ServiceConfig<DemoServiceImpl> service = new ServiceConfig<>();
        //为服务配置设置服务接口
        service.setInterface(DemoService.class);
        //为服务配置设置服务接口对应的服务实现
        service.setRef(new DemoServiceImpl());
       //获取Dubbo启动器
        DubboBootstrap bootstrap = DubboBootstrap.getInstance();
        //为Dubbo启动器设置应用配置 这里只设置一个应用名字
        bootstrap.application(new ApplicationConfig("dubbo-demo-api-provider"))
           //为启动器设置注册中心配置(配置中心和元数据可以不用配置模式会选择注册中心的配置)
            .registry(new RegistryConfig("zookeeper://127.0.0.1:2181"))
            //设置RPC通信协议配置为Dubbo协议
            .protocol(new ProtocolConfig(CommonConstants.DUBBO, -1))
            //设置当前Dubbo应用的服务配置
            .service(service)
            //启动Dubbo提供者应用
            .start()
            //等待应用结束
            .await();
    }
}

运行main方法启动程序即可。

存储在Zookeeper的三大中心节点数据

启动服务,这个时候我们打开Zookeeper图形化客户端来看看这个服务在Zookeeper上面写入了哪些数据,如下图:
image-20230107202837414

这里我们使用同一个Zookeeper集群进行三大中心的数据存储,应用级服务注册主要包含了一个服务名字和IP端口信息,元数据信息主要包含具体的服务接口信息。

如果了解Dubbo2.X老版本的同学应该可以看到原先Dubbo低版本的接口级的服务数据被拆分为了多个部分:元数据、应用级数据、配置数据。细化后的服务数据拆分看似复杂了其实有效的解决了传统接口级服务发现模型的性能存储问题。

在这里通过服务提供者的示例简单介绍了一下Dubbo3,可以先大致了解下,在后面会有更详细的Dubbo3源码解析系列来剖析Dubbo3源码, 通过透析代码来看透Dubbo3服务注册原理,服务提供原理, 如果感兴趣可以关注微信公众号 《中间件源码》 订阅后续内容吧。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/151461.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

买英伟达RTX 30 系显卡送《穿越火线》大礼包,你心动了吗?

2022年下半年英伟达一口气推出了RTX 4090、4080、4070 Ti显卡&#xff0c;40系列中的4060也在准备中&#xff0c;而RTX 30 系列在新系列的光芒下显得有些暗淡。 面对40系列即将成为主流的这种情况下&#xff0c;英伟达势必要想一些办法清清30系列显卡的库存&#xff0c;于是英…

上半年要写的博客文章24

上半年要写的博客文章21 这里写自定义目录标题欢迎使用Markdown编辑器新的改变功能快捷键合理的创建标题&#xff0c;有助于目录的生成如何改变文本的样式插入链接与图片如何插入一段漂亮的代码片生成一个适合你的列表创建一个表格设定内容居中、居左、居右SmartyPants创建一个…

网络工程师备考6章(续3)

6.20 距离矢量路协议与RIP 动态路由协议的第一个分类:距离矢量和链路状态 什么是距离矢量,例如我要从成都自驾去北京,不知道怎么走,决定路径的方式可以问别人怎么到西安,到西安后再问别人下一条路径,怎么到郑州,到郑州再问别人。一跳一跳的不停问别人,类似于距离矢量协…

P2- 复信号 - 通讯原理

前言&#xff1a; 这里主要结合一下欧拉定理,介绍一下复信号 一 复数概念定义 复数有两种定义方式&#xff1a; 指数函数&#xff1a;&#xff08;通过欧拉公式展开可以得到对应的复数形式&#xff09; 复数&#xff1a;实部a, 虚部b 幅值:A 相位: 二 复信号 2.1 定义 复信…

深度学习程序的预处理

目录 引入 1、预定义符号 1、为什么oj的编译器是clang和gcc呐&#xff1f; 1、vs测试 2、gcc测试 2、#define 1、#define定义标识符 1、#define的花样使用 2、续行符\的使用 3、预处理文件的内容展示和为什么头文件不能重复包含 4、vs下如何生成预处理后的文件&#xff1…

高分综述:人类肠道病毒组分类的进展和挑战

期刊&#xff1a;Cell Host Microbe 影响因子&#xff1a;31.316发表时间&#xff1a;2022.7 - 一、摘要 -人类肠道病毒组通常被称为肠道微生物组的“暗物质”&#xff0c;仍未得到充分研究。了解不同人群肠道病毒组的组成和变化对于探索其对人类健康的影响至关重要。人类肠道病…

聊透Spring事件机制

1、概述 事件机制是Spring为企业级开发提供的神兵利器之一&#xff0c;它提供了一种低耦合、无侵入的解决方式。 但其实Spring事件的设计其实并不复杂&#xff0c;它由三部分组成&#xff1a;事件、发布器、监听器。事件是主体&#xff0c;发布器负责发布事件&#xff0c;监听…

Lottie简介 + 结合到vue3中使用

Lottie简介 结合封装到vue3中使用前言&#xff1a;一、Lottie是什么1. 官方介绍2. 实现流程3. 动画资源二、为什么要选择Lottie三、lottie-web的使用1. 安装导入2. 初始化动画实例3. lottie-web支持的控制动画的主要方法4. lottie-web支持的监听动画的常用的事件四、lottie-we…

C++字符编码详解及利用string遍历中文字符串

作者&#xff1a;非妃是公主 专栏&#xff1a;《笔记》《C》 个性签&#xff1a;顺境不惰&#xff0c;逆境不馁&#xff0c;以心制境&#xff0c;万事可成。——曾国藩 文章目录C遍历英文字符串C遍历中文字符串&#xff08;不会出问题情况&#xff09;C遍历中文字符串&#xff…

Linux基础——进程的概念和控制(操作系统级讲解)

前言 我们经常会听到一个概念——进程。但是进程并不是一个孤立的概念&#xff0c;需要对操作系统有比较深入的了解。所以这篇博客将在读者的脑中先对操作系统构建一个大概的印象&#xff0c;再对进程做了解。 冯诺依曼结构 冯诺依曼结构也称普林斯顿结构&#xff0c;是一种…

微信小程序|智能停车系统中车牌计费功能实现

&#x1f4cc;个人主页&#xff1a;个人主页 ​&#x1f9c0; 推荐专栏&#xff1a;小程序开发成神之路 --【这是一个为想要入门和进阶小程序开发专门开启的精品专栏&#xff01;从个人到商业的全套开发教程&#xff0c;实打实的干货分享&#xff0c;确定不来看看&#xff1f; …

数据结构基础篇》》约瑟夫环

数据结构开讲啦&#xff01;&#xff01;&#xff01;&#x1f388;&#x1f388;&#x1f388; 本专栏包括&#xff1a; 抽象数据类型线性表及其应用栈和队列及其应用串及其应用数组和广义表树、图及其应用存储管理、查找和排序将从简单的抽象数据类型出发&#xff0c;深入浅出…

python 基础入门

文章目录前言python 基础入门一、python环境如何搭建、开发工具pycharm如何破解01 python下载02 python 安装03 python开发工具安装(pycharm )03::01 安装pycharm03::02 多次试用二、python 常规基础01 python 规范02 python中的关键字03 python缩进04 python注释哈哈哈前言 如…

07-JVM 类加载机制?

1.JVM 类加载机制分为五个部分&#xff1a;加载&#xff0c;验证&#xff0c;准备&#xff0c;解析&#xff0c;初始化。 2.一个类型从被加载到虚拟机内存中开始&#xff0c;到卸载出内存为止&#xff0c;它的整个生命周期将会经历加载&#xff08;Loading、验证&#xff08;V…

分布式版本控制Git

从基本的环境配置与安装到Git的基本操作&#xff0c;轻松应对Git在使用时遇到的常见问题。 https://blog.csdn.net/a18307096730/article/details/124586216?spm1001.2014.3001.550202_版本控制器的方式03_svn(过时)_git04git工作流程简述05git环境配与安装06 获取本地仓库Git…

P3375 【模板】KMP字符串匹配

题目描述 给出两个字符串 s_1s1​ 和 s_2s2​&#xff0c;若 s_1s1​ 的区间 [l, r][l,r] 子串与 s_2s2​ 完全相同&#xff0c;则称 s_2s2​ 在 s_1s1​ 中出现了&#xff0c;其出现位置为 ll。 现在请你求出 s_2s2​ 在 s_1s1​ 中所有出现的位置。 定义一个字符串 ss 的 bor…

概率论【离散型二维变量与连续性二维变量(上)】--猴博士爱讲课

5.离散型二维变量与连续性二维变量&#xff08;上&#xff09; 1/8 已知二维离散型分布律&#xff0c;求??? 离散型直接看表 【做题方法参考如下】 2/8 已知二维离散型分布律&#xff0c;判断独立性 如果满足p(xy) p(x) * p(y)&#xff0c;那么相互独立 则我们只需要验证每…

C 程序设计教程(12)—— C 语言顺序结构程序设计

C 程序设计教程&#xff08;12&#xff09;—— C 语言顺序结构程序设计 该专栏主要介绍 C 语言的基本语法&#xff0c;作为《程序设计语言》课程的课件与参考资料&#xff0c;用于《程序设计语言》课程的教学&#xff0c;供入门级用户阅读。 目录C 程序设计教程&#xff08;1…

深入探索Flutter性能优化

前言 Flutter 作为目前最火爆的移动端跨平台框架&#xff0c;能够帮助开发者通过一套代码库高效地构建多平台的精美应用&#xff0c;并支持移动、Web、桌面和嵌入式平台。对于 Android 来说&#xff0c;Flutter 能够创作媲美原生的高性能应用&#xff0c;但是&#xff0c;在较…

【nvivo11plus教程】02_编码与节点

1、对文档进行编码(1)建立节点(2)使用快速编码栏进行编码(3)将整个文件编码为一个代码(4)范围编码(5)在vivo中编码(6)使用节点昵称加快编码速度2、取消、增加和查看编码(1)编码带(2)删除编码(3)查看编码邻近区(4)增加编码(5)查看编码信息3、组织节点(1)节点结构化(2)移动归类节…