中文官网: Apache Dubbo
dljd:springcloud也是一个分布式框架。springcloud是dubbo的直接竞争对手,目前阶段dubbo和springcloud的使用各占一半,即50%,因此这两个框架大家都必须得掌握。
dljd:对RMI的理解,有助于我们以后学习dubbo和springcloud
一 需求调研、需求分析(即应用场景)
- Dubbo既然是一个RPC框架,那么主要干的就是远程过程(方法)调用。
- Dubbo是一个高性能的RPC框架解决了分布式中的调用问题。优点:解决了分布式系统中互相调用的问题。缺点:假设有100台服务器,50台用户业务服务器,50台订单业务服务器,但是在上线后发现,用户服务器使用率很小,但是订单服务器压力很大,最佳配比应该是1:4,这时候就要求我们还有一个统一管理的调度中心(即注册中心Zookeeper)。
-
Apache Dubbo 是一-款高性能、 轻量级的开源Java RPC框架,它的核心能力有:
-
面向接口代理的高性能RPC调用。提供高性能的基于代理的远程调用能力,服务以接口为粒度,为开发者屏蔽远程调用底层细节。
说明:使用dubbo时,dubbo底层是生成代理对象,而开发者面向的就是这些代理对象。
“服务以接口为粒度”是指dubbo对外提供的都是一个完整的业务功能,而且提供的这个业务功能的粒度是最小的。
“为开发者屏蔽远程调用底层细节”是指开发者面向的是接口编程,开发者根本看不到dubbo生成的实现类。比如,我们在使用mybatis开发dao时,我们在访问dao接口的时候,我们并没有再去实现dao接口中的方法了,单单只有一个接口在那里。mybatis根据接口和mapper.xml文件生成相对应的代理对象,而我们用的就是mybatis帮我们生成的代理对象吧。 - 智能容错和负载均衡。内置多种负载均衡策略,智能感知下游节点健康状况,显著减少调用延迟,提高系统吞吐量。
- 以及服务自动注册和发现。支持多种注册中心服务,服务实例上下线实时感知。
-
高度可扩展能力。遵循微内核+插件的设计原则,所有核心能力如Protocol、Transport、Serialization被设计为扩展点,平等对待内置实现和第三方实现。
-
运行期流量调度。内置条件、脚本等路由策略,通过配置不同的路由规则,轻松实现灰度发布,同机房优先等功能。
-
可视化的服务治理与运维。提供丰富服务治理、运维工具:随时查询服务元数据、服务健康状态及调用统计,实时下发路由策略、调整配置参数。
-
二 框架的设计思想
- RPC:远程过程调用。
三 体系的组织结构设计(重要组件、模块划分、模块间交互)
图1-官-dubbo的基本架构
四 工作原理
高性能要从底层的原理说起,既然是一个RPC框架,主要干的就是远程过程(方法)调用,那么提升性能就要从最关键、最耗时的两个方面入手:序列化和网络通信(RPC最关键的就是通过网络进行传输)。
序列化:我们学习Java网络开发的时候知道本地的对象要在网络上传输,必须要实现Serializable接口,也就是必须序列化。我们序列化的方案很多: xml、json、二进制流.. .其中效率最高的就是二进制流(因为计算机就是二进制的)。然而Dubbo采用的就是效率最高的二进
制。
网络通信:不同于HTTP 需要进行7步走(三次握手和四次挥手),Dubbo采用Socket通信机制,一步到位提升了通信效率,并且可以建立长连接不用反复连接,直接传输数据。
五 运行流程
图2-dljd-Dubbo 服务的实现原理
运行流程1:
- 0.start:当系统初始化的时候,要把Provider注册到Container里面。因为dubbo本身跟spring是无缝连接的,所以说Container指的就是spring容器。
- 1.register:把Provider提供的服务,注册到注册中心。
- 2.subscribe:Consumer项目启动以后要去Registry订阅Provider提供的、注册的这些服务。比如说,Provider注册了A、B、C这3个服务,那么Consumer就要去Registry订阅这3个服务。在这里,其实Consumer也要注册到spring容器中的。
- 3.notify:Consumer去Registry订阅服务成功以后,Registry会把A、B、C这3个服务地址返回给Consumer。
- 4.invoke:Consumer拿到Registry返回的A、B、C这3个服务地址以后,Consumer会通过A、B、C这3个地址去调用Provider提供的具体的这3个服务。
- count:不管你是Provider注册服务的时候,还是Consumer去消费服务的时候,都会向Monitor发一个请求,告知Monitor现在的(注册、消费)运行状态和情况。一旦出了问题,那么监控中心(Monitor)就会发出警告。
运行流程2:
- 0.start:比如大家用美团订外卖,Container就好比美团的商家客户端app。商家就好比这个Provider,商家要在Container注册一个店铺吧。
- 1.register:然后商家Provider要把他的外卖产品发布到店铺Registry中,有什么菜。
- 2.subscribe:消费者Consumer也要注册美团app消费者客户端Container,并登录。消费者Consumer就去店铺Registry看有什么菜(服务),然后订饭吧。
- 3.notify:消费者Consumer在店铺Registry并订饭后,店铺Registry会告诉我们订饭成功吧。
- 4.invoke:消费者Consumer在店铺Registry并订饭成功后,消费者Consumer就可以在指定时间内去商家Provider进行线下取饭(店内自取)了。
- 5.count:消费者Consumer和商家Provider,都会在Monitor的监视下完成交易的。
六 详细设计:实现方法(技术)
- dubbo是用java开发的框架。
- Dubbo 的底层实现是动态代理(java的socket编程 + 动态代理设计模式),由 Dubbo 框架创建远程服务(接口)对象的代理对象, 通过代理对象调用远程方法。
七 使用说明:常用配置
八 附:dubbo 支持的协议
<dubbo:protocol name="dubbo" port="20880" />
说明:如何理解dubbo框架支持协议?
首先,Consumer是一台服务器,Provider也是一台服务器。
其次,Consumer获取Registry返回来的服务提供者的地址列表之后 (3.notify),Consumer去调用Provider的具体服务(4.invoke)的时候,需要遵守一种协议。dubbo支持很多种调用协议。这好比,我们在浏览器地址栏上使用http协议是一样的,比如http://www.baidu.com来访问百度搜索首页,这就是在遵循http协议。再比如,我们使用ftp去打开共享目录,这里的ftp//...也是一种协议,还可以通过ftp去下载一些文档、图片、音视频吧,这加遵循的是ftp协议。
也就是说http(默认端口号8080)协议是我们去访问别的网站时推荐使得的协议,而ftp是我们去打开共享目录下载东西时推荐使用的协议。而在duboo项目中,Consumer去访问Provider的具体服务器,dubbo推荐我们使用的是dubbo协议,默认端口号是20880。
最后,dubbo推荐使用的是自己定义的dubbo协议,dubbo协议默认的端口号是20880。
九 附:dubbo注册中心分类
Dubbo 提供 的注册中心有如下几种类型可供选:
- Multicast 注册中心:组播方式
- Redis 注册中心:使用 Redis 作为注册中心
- Simple 注册中心:就是一个 dubbo 服务。作为注册中心。提供查找服务的功能。
- Zookeeper 注册中心:使用 Zookeeper 作为注册中心
十 附:分布式 —— 思想
1、什么是分布式框架(设计思想)
分布式系统是若干独立系统的集合,但是用户使用起来像是在使用一套系统。
说明:集中式开发:把所有的功能模块集中到一个工程(项目)中去开发,我们以前所做的开发(ssh、ssm)都属性集中式开发。分布式系统:把一个系统拆分成若干个系统的集合。
2、为什么需要分布式系统(应用场景)
规模的逐步扩大和业务的复杂,单台计算机扛不住双十一那样的流量,俗话说:三个臭皮匠抵一个诸葛亮。
说明:一台服务器根本顶不了像双十一那么的流量,像有名的电商在双十一都会启用上1000台服务器。如果说使用的集中式开发的项目,那么对系统的升级或修改就要同时对上1000台服务器里面的应用进行一个一个地升级和修改。而如果说使用的是分布式开发,那么我们可以查看各个子系统(节点)的访问流量,对访问流量大的独立的子系统进行升级或修改就可以了,其它独立子系统可以原封不动。
3、应用架构的发展演变(工作原理、运行流程)
(1)单一架构
当网站流量很小的时候,我们将所有的应用(业务)放到一台服务器上,打包运行。比如,公司管理系统/超市收银系统。
优点:开发简单,部署简单
缺点:扩展不容易(怎么处理日益增长的流量),谁都改一个 ,维护不容易,性能提升难。
(2)垂直应用架构(A调B,B再调C,C接着调D,D最后调用E......)
将大应用拆分成为小应用(一般按照业务拆分),根据不同的访问频率决定各自业务部署的服务器的数量。
优点:扩展容易
缺点:页面一改,可能造成整个项目重新部署,业务和界面没有分离开,随着业务种类增加,怎么解决业务之间的互相调用问题,订单服务器和用户服务器交互效率的问题。
(3)分布式架构(基于RPC:远程过程调用)
将业务拆分后,用某种方式实现各个业务模块的远程调用和复用。 这时一个好的RPC框架就决定了你的分布式架构的性能,怎么调用?何时调用?服务器挂了怎么办......。我们需要一个框架来帮我们解决这个问题(当然大大神可以自己写一个,但是应对大流量的成功者莫过于中国的阿里巴巴公司,顶住了淘宝双十一的流量。反观一些学校内部的选课系统,对于大流量时只有两个字——宕机)。
4、实现方法
一个好的RPC框架
十一 附:RPC:远程过程调用 —— 思想
1、定义
- 调用方的角度:简单地说就是能使应用像调用本地方法一样的调用远程的过程或服务。
- 被调用方的角度:说白了,RPC(远程过程调用),也就是说,直接调用的是它所提供的服务,它把这个服务让别人去调用。
4、工作原理、运行流程
图1-百度百科-远程过程调用流程图
图2-dljd-远程过程调用流程图
6、RPC与其他远程调用的比较
- HTTP:HTTP (HyperText Transfer Protocol) 是应用层通信协议,使用标准语义访问指定资源(图片、接口等),网络中的中转服务器能识别协议内容。HTTP协议是一种资源访问协议,通过HTTP协议可以完成远程请求并返回请求结果。HTTP的优点是:简单、易用、可理解性强且语言无关,在远程服务调用中包括微博有着广泛应用。HTTP的缺点是:协议头较重,一般 请求到具体服务器的链路较长,可能会有DNS解析、Nginx代理等。
- RPC:RPC是一种协议规范,可以把HTTP看作是一种RPC的实现,也可以把HTTP作为RPC的传输协议来应用。RPC服务的自动化程度较高,能够实现强大的服务治理功能,和语言结合更友好,性能也十分优秀。与HTTP相比,RPC的缺点就是相对复杂,学习成本稍高。
- RMI:
- dljd:对RMI的理解,有助于我们以后学习dubbo和springcloud。
- dljd:如果说RPC是一种思想,RMI恰恰是在java中对RPC的一个实现方式。RMI的实现方式,经过我们的分析呢,其内部实际上就是java的socket编程加上代理设计模式。
- RMI ( Remote Method Invocation)是指java语言中的远程方法调用,RMI中的每个方法都具有方法签名,RMI客户端和服务端通过方法签名进行远程方法调用。RMI只能在Java语言中使用,可以把RMI看作面向对象的java RPC。
- web service:Web Service是一种基于Web进行服务发布、查询、调用的架构方式,重点在于服务的管理与使用。Web Service一般通过WSDL (基于XML的网络服务描述语言)描述服务,使用SOAP (简单对象访问协议)通过HTTP调用服务。RPC是一 种远程访问协议,而Web Service是一 种体系结构。WebService也可以通过RPC来进行服务调用,因此Web Service更适合同一个RPC框架进行比较。当RPC框架提供了服务的发现与管理,并使用HTTP作为传输协议时,其实就是Web Service。
十二 附:注册中心Zookeeper(调度中心)
1、理解“注册中心Zookeeper(调度中心)”
说明:“注册中心Zookeeper”,即我们的调度中心,帮我们统一管理的调度。“注册中心Zookeeper”就相当于中控大脑,它要去分配各个路线的资源使用比例(各调度比例),来达到一个最协调的方式。比如公交站、客运站、火车、飞机航班的调度,就是分配各个航线的比例。如果一条航线每天就有2~3个人,那就不可能每天都飞10躺航班吧,给开一躺都不错了。如果有的航线天天爆满,这时还每天1躺航班是满足不了需求的。上面两种情况,很明显就是调度有问题。
2、需求调研、需求分析(即应用场景)
-
Zookeeper通过将服务(服务接口)统一管理起来,可以有效地优化内部应用对服务发布 /使用(调度)的流程和管理,保证provider提供的服务与 Consumer消费的 最佳配比 。dubbo的缺点:假设有100台服务器,50台用户业务服务器,50台订单业务服务器,但是在上线后发现,用户服务器使用率很小,但是订单服务器压力很大,最佳配比应该是1:4,这时候就要求我们还有一个统一管理的调度中心,也就是我们要讲的“注册中心Zookeeper”了。
3、框架的设计思想
- zookeeper是一个树型的目录服务,支持变更推送。
说明:什么是目录呀?什么是树型?比如我们的计算机,第一层是“我的电脑”;第二层是“各个盘符”;第三层是“盘符中的各个文件夹”;最后一层是“各个文件夹中的文件吧”。以上这些都是目录,而且他们的组织方式可以用树型来表示吧。这里的目录,也可以称为节点。也就是说zookeeper在管理服务的时候,也是按照树型的目录结构来进行服务的管理的。
说明:”支持变更推送“指的是:如果provider提供的服务有变更,zookeeper也会推送变更后的服务列表。
- 服务注册中心可以通过特定协议来完成服务对外的统一。
4、体系的组织结构设计(重要组件、模块划分、模块间交互)
图1-dubbo官网-zookeeper
首先ROOT:为什么zookeeper能够保证唯一性呢? 你看,zookeeper都会有一个根叫Root,而Root也叫dubbo,Root就是dubbo。
然后Service,第一个dubbo(root)里边,它都会有零个或多个Service节点。这个Service节点,就是provider对外提供的服务的接口的全限定类名。说白了,就是一个文件夹,如上图所示这个文件夹的名称就叫做com.foo.BarService,当然还有很多Xxx.xxx.XxxService文件夹吧。也就是说,每一个服务都对应一个service节点。
接着Type,每个服务节点service下面都会有两种角色,一个是provier和consumer。
最后URL,在provider这里,zookeeper会记录服务器的地址和端口(如上图的10.20.153.10:20880)标识provider提供的是什么服务。这里会有很多provider,提供了很多服务;consumer这边,zookeeper会记录consumer使用哪个地址调用了哪个provider提供的什么服务。
总结,所以说zookeeper管理服务的方式就是树型结构的。
6、工作原理\运行流程
图2-dljd dubbo-zookeeper
流程说明:
- 服务提供者启动时: 向
/dubbo/com.foo.BarService/providers
目录下写入自己的 URL 地址 - 服务消费者启动时: 订阅
/dubbo/com.foo.BarService/providers
目录下的提供者 URL 地址。并向/dubbo/com.foo.BarService/consumers
目录下写入自己的 URL 地址 - 监控中心启动时: 订阅
/dubbo/com.foo.BarService
目录下的所有提供者和消费者 URL 地址。
dljd说明:
当没有使用Zookeeper的开发的时候,consumer去消费由provider提供的服务的方式是,在consumer的代码中自己指定服务的地址。
Zookeeper的作用相当于一本笔记本,当有了Zookeeper了以后:
首先,provider会把它提供的服务的地址告诉Zookeeper,Zookeeper就会这些服务地址一一记录下来。
然后,consumer就去Zookeeper获取可用的那些服务。
7、详细设计:实现方法(技术)
8、dljd:zoo.cfg配置详解
原来就有的:
- tickTime:不动
- initLimit:不动
- syncLimit:不动
- dataDir:指定到zookeeper安装的根目录的data中
- clientPort:指定zookeeper这个服务的端口号,zookeeper它本身也是一个服务呀,在任何系统里面zookeeper这个服务默认使用的端口号都是2181,这个值一般我们都不改动。
- admin.serverPort=8888 原因:zookeeper 3.5.x 占用 8080。说明:因为在我们启动zookeeper的时候,zookeeper内部需要去启动另外一个服务,而那个服务所占用的端口号是8080。而8080是我们习惯去使用的的端口号,所以通常我们会改成8888。其实不改也可以,只是不能再用8080这个端口号了。
十三 其它
图-旧官网-dubbo服务治理