从一个 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编程 ...
随机推荐
- quarkus依赖注入之三:用注解选择注入bean
欢迎访问我的GitHub 这里分类和汇总了欣宸的全部原创(含配套源码):https://github.com/zq2599/blog_demos 本篇概览 本文是<quarkus依赖注入> ...
- ChatGPT 助力开发人员改进代码的5个方式
近年来,在软件开发中使用人工智能和机器学习变得越来越普遍.因此,开发人员开始转向像 OpenAI 的 ChatGPT 这样的工具来简化他们的工作,提高他们的工作效率.ChatGPT是一个由 OpenA ...
- 青少年CTF平台-Web-Flag在哪里
平台名称:青少年CTF训练平台 题目名称:Flag在哪里? 解题过程: 启动环境,需要等待大概20秒左右的时间. 访问,页面显示Flag反正不在这. 右键网页,发现无法使用右键. 那么我们直接F12 ...
- css里的position的static|relative|absolute|fixed的区别
前提:仅以div块为例,其它不清楚 注:1.下面截图看起来不是从页面左上角位置开始,是因为body元素有默认的margin,有边框 2.当position不是static时,top和bottom需要指 ...
- Zimbra禁止接收带有加密的文件邮件 提醒病毒(Heuristics.Encrypted.PDF)
最近碰到一个国际性大客户,一定要发送经过加密的文件,因为是合约相关的文件,对方公司有这方面要求.但是Zimbra默认是禁止接收加密的文件 - 'Block encrypted archives',这样 ...
- P1830题解
思路: 利用桶存储轰炸区域,双重循环. 在存储轰炸区域时将次数刷新,也就是pos[j][k]=i;. 下面是核心代码: for(int i=1;i<=x;i++) { int x1,x2,y1, ...
- API技术的使用场景
互联网的发展和普及,API技术也变得越来越重要.API是应用程序接口,它是一种连接不同应用程序或系统之间数据交换和通信的方式.API技术不仅提高了不同应用程序之间的互操作性,还加速了应用程序的开发 ...
- C语言指针函数和函数指针区别(转)
C语言函数指针和指针函数的区别C和C++中经常会用到指针,和数据项一样,函数也是有地址的,函数的地址是存储其机器语言代码的内存的开始地址. 指针函数和函数指针经常会混淆,一个是返回指针的函数,另一个是 ...
- SpringSecurity-前后端分离教程
1.简介 Spring Security 是 Spring 家族中的一个安全管理框架.相比与另外一个安全框架Shiro,它提供了更丰富的功能,社区资源也比Shiro丰富. 一般来说中大型的项目都是使用 ...
- 13.1 使用DirectX9绘图引擎
DirectX 9 是由微软开发的一组多媒体应用程序接口API,用于创建和运行基于Windows平台的多媒体应用程序,尤其是游戏.它是DirectX系列中的一个版本,于2002年发布,是DirectX ...