Dubbo的一些学习使用总结
1.什么是Dubbo
Dubbo是一个分布式服务框架,Dubbo的产生让我们告别了http+restful和webservice进行服务数据交互的模式,而Dubbo采用的是分布式SOA服务治理方案,通过RPC远程调用服务。
SOA:简单来说是一种服务体系规范,低耦合,根据业务逻辑将服务分割成细小部分分布式部署的服务架构。
RPC:一种远程网络服务通讯协议,封装了TCP/IP协议,我们不用关心底层实现,而只需要指定IP地址以及端口号,找到到我们需要的服务端,得到我们需要的服务。
2.Dubbo的主要功能
远程通讯: 提供对多种基于长连接的NIO框架抽象封装,包括多种线程模型,序列化,以及“请求-响应”模式的信息交换方式。
集群容错: 提供基于接口方法的透明远程过程调用,包括多协议支持,以及软负载均衡,失败容错,地址路由,动态配置等集群支持。
自动发现: 基于注册中心目录服务,使服务消费方能动态的查找服务提供方,使地址透明,使服务提供方可以平滑增加或减少机器。
3.Dubbo的架构
Dubbo中主要角色:
- Provider: 暴露服务的服务提供方。
- Consumer: 调用远程服务的服务消费方。
- Registry: 服务注册与发现的注册中心。
- Monitor: 统计服务的调用次调和调用时间的监控中心。
- Container: 服务运行容器。
调用关系:
- 服务容器负责启动,加载,运行服务提供者。
- 服务提供者在启动时,向注册中心注册自己提供的服务。
- 服务消费者在启动时,向注册中心订阅自己所需的服务。
- 注册中心返回服务提供者地址列表给消费者,如果有变更,注册中心将基于长连接推送变更数据给消费者。
- 服务消费者,从提供者地址列表中,基于软负载均衡算法,选一台提供者进行调用,如果调用失败,再选另一台调用。
- 服务消费者和提供者,在内存中累计调用次数和调用时间,定时每分钟发送一次统计数据到监控中心。
4.Dubbo官方文档架构分层解释
服务接口层(Service):该层是与实际业务逻辑相关的,根据服务提供方和服务消费方的业务设计对应的接口和实现。
配置层(Config):对外配置接口,以ServiceConfig和ReferenceConfig为中心,可以直接new配置类,也可以通过spring解析配置生成配置类。
服务代理层(Proxy):服务接口透明代理,生成服务的客户端Stub和服务器端Skeleton,以ServiceProxy为中心,扩展接口为ProxyFactory。
服务注册层(Registry):封装服务地址的注册与发现,以服务URL为中心,扩展接口为RegistryFactory、Registry和RegistryService。可能没有服务注册中心,此时服务提供方直接暴露服务。
集群层(Cluster):封装多个提供者的路由及负载均衡,并桥接注册中心,以Invoker为中心,扩展接口为Cluster、Directory、Router和LoadBalance。将多个服务提供方组合为一个服务提供方,实现对服务消费方来透明,只需要与一个服务提供方进行交互。
监控层(Monitor):RPC调用次数和调用时间监控,以Statistics为中心,扩展接口为MonitorFactory、Monitor和MonitorService。
远程调用层(Protocol):封将RPC调用,以Invocation和Result为中心,扩展接口为Protocol、Invoker和Exporter。Protocol是服务域,它是Invoker暴露和引用的主功能入口,它负责Invoker的生命周期管理。Invoker是实体域,它是Dubbo的核心模型,其它模型都向它靠扰,或转换成它,它代表一个可执行体,可向它发起invoke调用,它有可能是一个本地的实现,也可能是一个远程的实现,也可能一个集群实现。
信息交换层(Exchange):封装请求响应模式,同步转异步,以Request和Response为中心,扩展接口为Exchanger、ExchangeChannel、ExchangeClient和ExchangeServer。
网络传输层(Transport):抽象mina和netty为统一接口,以Message为中心,扩展接口为Channel、Transporter、Client、Server和Codec。
数据序列化层(Serialize):可复用的一些工具,扩展接口为Serialization、 ObjectInput、ObjectOutput和ThreadPool。
各层之间关系:
在RPC中,Protocol是核心层,也就是只要有Protocol + Invoker + Exporter就可以完成非透明的RPC调用,然后在Invoker的主过程上Filter拦截点。
Consumer和Provider是抽象概念,只是抽象的表示了客户端与服务器端,不用Client和Server的原因是Dubbo在很多场景下都使用Provider、Consumer、Registry、Monitor划分逻辑拓普节点,保持统一概念。
而Cluster是外围概念,所以Cluster的目的是将多个Invoker伪装成一个Invoker,这样其它人只要关注Protocol层Invoker即可,加上Cluster或者去掉Cluster对其它层都不会造成影响,因为只有一个提供者时,是不需要Cluster的。
Proxy层封装了所有接口的透明化代理,而在其它层都以Invoker为中心,只有到了暴露给用户使用时,才用Proxy将Invoker转成接口,或将接口实现转成Invoker,也就是去掉Proxy层RPC是可以Run的,只是不那么透明,不那么看起来像调本地服务一样调远程服务。
而Remoting实现是Dubbo协议的实现,如果你选择RMI协议,整个Remoting都不会用上,Remoting内部再划为Transport传输层和Exchange信息交换层,Transport层只负责单向消息传输,是对Mina、Netty、Grizzly的抽象,它也可以扩展UDP传输,而Exchange层是在传输层之上封装了Request-Response语义。
Registry和Monitor实际上不算一层,而是一个独立的节点。
5.提供服务者(service层)
<dubbo:application name="serviceXXX" />
<!--取个名字,用于后台监听调用该服务调用情况-->
<dubbo:registry protocol="zookeeper" address="ip1,iP2,..." />
<!--服务注册中心为zookeeper,地址可以是多个-->
<dubbo:protocol name="dubbo" port="20880" />
<!-- 用dubbo协议在20880端口暴露服务 name值为固定写法 -->
<dubbo:service interface="xxx.service.TestService" ref="testServiceImpl"/>
<!-- 声明需要暴露的服务接口 -->
其中 dubbo:service 还有一些常用属性可以配置
version:服务版本,建议使用两位数字版本,如:1.0,通常在接口不兼容时版本号才需要升级。
group:服务分组,当一个接口有多个实现,可以用分组区分,比如生产环境和线上环境服务区分。
timeout:远程服务调用超时时间(毫秒),客户端和服务端均可配置,优先级客户端>服务端。
retries:远程服务调用重试次数,不包括第一次调用,不需要重试请设为0,写操作重试可能导致数据出现问题。(因为调用超时不代表服务端流程没有执行)
loadbalance:负载均衡策略,可选值:random,roundrobin,leastactive,分别表示:随机,轮循,最少活跃调用。
async:默认为false,是否缺省异步执行,不可靠异步,只是忽略返回值,不阻塞执行线程。
token:令牌验证,为空表示不开启,如果为true,表示随机生成动态令牌,否则使用静态令牌,令牌的作用是防止消费者绕过注册中心直接访问,保证注册中心的授权功能有效,如果使用点对点调用,需关闭令牌功能。
executes:服务提供者每个服务每个方法的最大可并行执行请求数。
filter:服务提供方远程调用过程拦截器名称,多个名称用逗号分隔。可以自己对访问接口搞访问IP黑白名单。
(因为spring只会对web访问进行拦截,不会对dubbo接口拦截)
还可以细到方法设置 dubbo:method
6.服务消费者
<dubbo:application name="comsumerXXX"/>
<!--命令消费者,供后台监听服务消费情况-->
<dubbo:registry protocol="zookeeper" address="ip1,ip2,..."/>
<!--指明服务中心和地址-->
<dubbo:reference interface="xxx.service.TestService" id="testService" />
<!--生成代理,通过id设置bean名字,使用-->
7.服务监听者
可以下载dubbo-admin 在linux上通过tomcat配置,2.6以上版本整合到了springboot,2.6以下的可以在网上找一下,注意不同的dubbo-admin对tomcat版本要求不同。
配置完成后,可访问tomcat对应地址,输入dubbo-admin默认的账户信息查看dubbo的服务消费使用情况。
8.服务注册中心
Zookeeper和Eureka的对比
当然,因为是配合dobbu使用,所以主要说一下Zookeeper
ZooKeeper的优点:它是一个成熟的开源社区活跃度高的分布式的,开放源码的分布式应用程序协调服务,用于监听注册的服务情况,适当的分配服务给消费者。主要作用:1.命名服务 2.配置管理 3.集群管理 4.分布式锁 5.队列管理 。通过这些保证消费者调用正确的服务。
Zookeeper的缺点:
1.它设计之初是为了满足CP原则,而CP原则和满足AP原则的(Eureka)服务发现注册中心区别简单理解就在于CP太武断,AP更中庸。而显然中庸更符合服务发现。作为CP一刀切设计的Zookeeper在发现服务功能上是不适合我们的需求的,如果发现的服务返回信息有错误,Zookeeper就会直接断掉,而同样情况下AP的Eureka会返回之前一段时间正确的服务信息。
当然你可以选择一些第三方的方法进行Zookeeper服务缓存,但这有些像在CP的zookeeper上强加一个AP的缓存实现组件。
2.当Zookeeper的master服务中心挂掉了,它会通过vote投票选举的方式,选出新一个leader来继续维持服务,但是这一过程需要一定的时间,可能会达到几十秒甚至一两分钟,显然对用户请求来说有些长的,并且在极端情况下比如只剩下2台服务器,出现1:1的投票时,Zookeeper会面临挂掉的风险。而Eureka则是直接自动更换一台维持服务。
那为什么不选择Eureka而使用Zookeeper呢?
其实服务中心的选择是有很多的,对Eureka来说,确实吸取了Zookeeper的经验,进而采用AP设计模式,是青出于蓝而胜于蓝的考虑,但是Zookeeper确实也能满足我们生产需求,并且也有自身的优势,和Dubbo搭配这么多年了,也非常成熟稳定。最后Eureka也是更多是搭配SpringCloud来配套使用的。
当然还有其他的比如Consul等等服务注册中心供大家选择。
Dubbo,Zookeeper服务端的安装就不多做赘述了,网上到处都有。