从一个 Demo 说起 Dubbo3
简介
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部署架构

可以看到Dubbo3的架构图里面新包含了三大中心的概念:
- 注册中心: 协调 Consumer 与 Provider 之间的地址注册与发现
- 配置中心: 存储 Dubbo 启动阶段的全局配置,保证配置的跨环境共享与全局一致性,负责服务治理规则(路由规则、动态配置等)的存储与推送。
- 元数据中心: 接收 Provider 上报的服务接口元数据,为 Admin 等控制台提供运维能力(如服务测试、接口文档等),作为服务发现机制的补充,提供额外的接口/方法级别配置信息的同步能力,相当于注册中心的额外扩展
可以看到这里比较新的概念元数据中心做的事情是用来存储服务接口的元数据,在Dubbo2中服务接口数据与应用数据都是存储在注册中心了,这里将接口元数据抽离到元数据中心,让注册中心专注于应用级服务发现。
应用级服务发现模型

应用级服务发现模型的粒度是以应用单元来进行服务发现的,Dubbo2中的接口级发现不仅仅会造成注册中心数据的膨胀,同时也无法让Dubbo应用于其他微服务框架的应用比如SpringCloud实现互联互通,在打通了地址发现之后,应用级服务发现使得用户探索用 Dubbo 连接异构的微服务体系成为了一种可能。
另外应用级服务发现模型会将元数据信息的获取下沉到一个RPC请求之中,这个让服务通知得以高效,如下图:
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上面写入了哪些数据,如下图:
这里我们使用同一个Zookeeper集群进行三大中心的数据存储,应用级服务注册主要包含了一个服务名字和IP端口信息,元数据信息主要包含具体的服务接口信息。
如果了解Dubbo2.X老版本的同学应该可以看到原先Dubbo低版本的接口级的服务数据被拆分为了多个部分:元数据、应用级数据、配置数据。细化后的服务数据拆分看似复杂了其实有效的解决了传统接口级服务发现模型的性能存储问题。
在这里通过服务提供者的示例简单介绍了一下Dubbo3,可以先大致了解下,在后面会有更详细的Dubbo3源码解析系列来剖析Dubbo3源码, 通过透析代码来看透Dubbo3服务注册原理,服务提供原理, 如果感兴趣可以关注微信公众号 《中间件源码》 订阅后续内容吧。
从一个 Demo 说起 Dubbo3的更多相关文章
- angular开发者吐槽react+redux的复杂:“一个demo证明你的开发效率低下”
曾经看到一篇文章,写的是jquery开发者吐槽angular的复杂.作为一个angular开发者,我来吐槽一下react+redux的复杂. 例子 为了让大家看得舒服,我用最简单的一个demo来展示r ...
- 初识nginx之第一个demo
商城项目做了一个多月了,想到必须用到负载均衡,简单了解了一下nginx,首先分享第一个demo,五月份上线后,会继续分享一系列相关知识. 在nginx根目录下,用了一个园友的批处理文件nginx.ba ...
- springMvc的第一个demo
1.下载jar包 http://repo.spring.io/libs-release-local/org/springframework/spring/4.2.3.RELEASE/ 2.下载源码 j ...
- Android 通知栏Notification的整合 全面学习 (一个DEMO让你完全了解它)
在android的应用层中,涉及到很多应用框架,例如:Service框架,Activity管理机制,Broadcast机制,对话框框架,标题栏框架,状态栏框架,通知机制,ActionBar框架等等. ...
- 如何在WTL和MFC中使用duilib及如何静态使用duilib库!(初级讲解 附带一个Demo)
关于duilib的历史,我也就不多说了,能看到这篇文章的人都是有一定了解才能找到这个的. 我直接说下对这个库的基本使用吧. 我个人对一些好技术都是比较感兴趣的. 因为个人原因 喜欢接触一个好技术. 所 ...
- 白盒测试之gtest第一个demo
认识gtest工具后,关于它的使用,下面将用一个demo程序演示一下gtest的用法以及成果展示. 一.需要测试的C++代码: #include "myfunction.h" // ...
- 在VS中实现webService的一个demo(图解)
在VS中实现webService的一个demo(图解) 先创建一个web项目,创建好web项目后,添加新建项——web服务 在新建好的web服务文件中写如下代码: 生成当前解决方案. 新建一个winf ...
- Cocos2d-x 学习(1)—— 通过Cocos Studio创建第一个Demo
近期在工作上有了比較大的转变,自学情绪也慢慢高涨,本来一直在研究unity的技术.由于换了工作会開始接触cocos2d-x.但并不意味着停止研究unity,以后有时间还是会继续的. 公司的cocos2 ...
- 使用android的mediaplayer做成 一个demo,欢迎测试使用
附件是为一个定制视频产品而简单的写了一个demo,用来说明android的mediaplayer是如何使用的. http://files.cnblogs.com/guobaPlayer/palyerD ...
- [置顶]
一个demo学会css
全栈工程师开发手册 (作者:栾鹏) 一个demo学会css css选择器全解 css操作语法全解 学习了css权威指南这本书,自己喜欢边学边总结边写demo,所以写了这篇文章,包含了大部分的css编程 ...
随机推荐
- 王道oj/problem16
网址:http://oj.lgwenda.com/problem/16 思路:都在注释里,注意增删查的参数以及停止条件 代码: #define _CRT_SECURE_NO_WARNINGS#incl ...
- 《UNIX 传奇:历史与回忆》读后感
<UNIX 传奇:历史与回忆> 是 bwk(Brian W. Kernighan)2019 年的新作,回忆了 UNIX 在大半个世纪的风雨历程,是一本引人入胜的书籍.通过对 UNIX 操作 ...
- linux设置信号量系统参数
前言 信号量是IPC(进程间通信)机制的一种,用于协调多个进程或线程对共享数据的读写操作,本质上是一个计数器.类似于锁,主要用于保护共享资源,控制同时访问资源的进程数. 信号量只允许调用者对它进行等待 ...
- react项目搭建-路由封装
router v6 路由统一管理与添加,对是否登录进行判断. 1.使用脚手架创建项目 新建一个文件夹 ,在文件夹内部打开命令行工具. 执行命令:npx create-react-app 项目名字 将项 ...
- API接口开发管理平台--多领域企业数字化管理解决方案
随着数字化时代的到来,企业需要进行数字化转型才能更好地适应市场需求和用户需求.而API接口则是数字化转型中的重要组成部分,可以帮助企业更好地管理信息,提高效率.本文将介绍挖数据解决方案--API接口开 ...
- DevOps |研发效能之环境、程序、配置、SQL变更管理
本文主要是讲如何建立有效的环境.程序.配置.SQL变更和管理平台. 几天前和一个朋友聊到环境.程序的配置变更,SQL变更和整个上线流程.之前我们在这块也做了很多,有做的好的也有做的一般的,借机都总结 ...
- springboot整合seata1.5.2+nacos2.1.1
一.前言 Seata出现前,大部分公司使用的都是TCC或者MQ(RocketMq)等来解决分布式事务的问题,TCC代码编写复杂,每个业务均需要实现三个入口,侵入性强,RocketMQ保证的是最终一致性 ...
- HTML一键打包APK工具最新版1.9.2更新(附下载地址)
HMTL网址打包APK,可以把本地HTML项目, Egret游戏,网页游戏,或者网站打包为一个安卓应用APK文件,无需编写任何代码,也无需配置安卓开发环境,支持在最新的安卓设备上安装运行. 打包软件会 ...
- Jquery 将 JSON 列表的 某个属性值,添加到数组中,并判断一个值,在不在数据中
jquery 将 JSON 列表的 某个属性值,添加到数组中 如果你有一个JSON列表,并且想要将每个对象的某个属性值添加到数组中,你可以使用jQuery的$.each()函数来遍历JSON列表,并获 ...
- 制作一个内部的 zabbix-agent 快速部署脚本
下载官方的基础 agent 部署包 官方地址:点击到达 curl -O https://cdn.zabbix.com/zabbix/binaries/stable/5.0/5.0.36/zabbix_ ...