简介:

Dubbo是一种分布式服务框架。 Webservice也是一种服务框架,但是webservice并不是分布式的服务框架,他需要结合F5实现负载均衡。因此,dubbo除了可以提供服务之外,还可以实现软负载均衡。它还提供了两个功能Monitor 监控中心和调用中心。这两个是可选的,需要单独配置。

Consumer服务消费者,Provider服务提供者。Container服务容器。消费当然是invoke提供者了,invoke这条实线按照图上的说明当然同步的意思了,多说一句,在实际调用过程中,Provider的位置对于Consumer来说是透明的,上一次调用服务的位置(IP地址)和下一次调用服务的位置,是不确定的。这个地方就是实现了软负载。

服务提供者先启动start,然后注册register服务

消费订阅subscribe服务,如果没有订阅到自己想获得的服务,它会不断的尝试订阅。新的服务注册到注册中心以后,注册中心会将这些服务通过notify到消费者。

Monitor这是一个监控,图中虚线表明Consumer和Provider通过异步的方式发送消息至Monitor,Consumer和Provider会将信息存放在本地磁盘,平均1min会发送一次信息,Monitor在整个架构中是可选的(图中的虚线并不是可选的意思),Monitor功能需要单独配置,不配置或者配置以后,Monintor挂掉并不会影响服务的调用。

一、dubbo缺省协议采用的是单一长连接和NIO异步通讯,适合于小数据量大并发的服务调用,以及服务消费者机器数远大于服务提供机器数的情况。

反之,Dubbo缺省协议不适合传送大数据量的服务,比如传文件,传视频等,除非请求量很低。

特性:

缺省协议,使用基于mina 和hessian的tbremoting交互

连接个数:单连接

连接方式:长连接

传输协议:TCP

传输方式:NIO异步传输

序列化:Hessian 二进制序列化

适用范围:传入传出参数数据包较小(建议小于100K),消费者比提供者个数多,单一消费者无法压满提供者,尽量不要用dubbo协议传输大文件或超大字符串

适用场景:常规远程服务方法调用

二、RMI
rmi协议采用JDK标准的java.rmi.*实现,采用阻塞式短连接和JDK标准序列化方式。

注意:如果正在使用RMI提供服务给外部访问,同时应用里依赖了老搭档common-collections包的情况下,存在反序列化安全风险

特性:

连接个数:多连接

连接方式:短连接

传输协议:TCP

传输方式:同步传输

序列化:Java标准二进制序列化

适用范围:传入传出参数数据包大小混合,消费者与提供者个数差不多,可传文件

适用场景:常规远程服务方法调用,与原声RMI服务互操作

三、hessian

Hessian协议用于集成Hessian的服务,Hessian底层采用Http通讯,采用Servlet暴露服务,Dubbo缺省内嵌Jetty作为服务实现。

Dubbo的Hession协议可以和原生Hessian服务互操作,即:

提供者用Dubbo的Hessian协议暴露服务,消费者直接用标准Hessian接口调用

或者提供方用标准Hessian暴露服务,消费方用Dubbo的Hessian协议调用

特性:

连接个数:多连接

连接方式:短连接

传输协议:HTTP

传输方式:同步传输

序列化:Hessian 二进制序列化

适用范围:传入传出参数数据包较大,提供者比消费者个数多,提供者压力较大,可传文件

适用场景:页面传输,文件传输,或与原生hessian服务互操作。

四、Http

基于Http表单的远程调用协议,采用Spring的HttpInvoker实现

特性:

连接个数:多连接

连接方式:短连接

传输协议:HTTP

传输方式:同步传输

序列化:表单序列化

适用范围:传入传出参数数据包大小混合,提供者比消费者个数多,可用浏览器看,可用表单或URL传入参数,暂不支持传文件。

适用场景:需同时给应用程序和浏览器JS使用的服务.

五、WebService

基于WebService的远程调用协议,基于Apache CXF 的frontend-simple和transports-http实现,,可以和原生WebService服务互操作,即:

提供者用Dubbo的WebService协议暴露服务,消费者直接用标准WebService接口调用,

或者提供者用标准的WebService暴露服务,消费者用Dubbo的WebService协议调用。

特性:

连接个数:多连接

连接方式:短连接

传输协议:HTTP

传输方式:同步传输

序列化:SOAP序列化

适用场景:系统集成,跨语言调用

六、thrift

当前dubbo支持的thrift协议是对thrift原生协议的扩展,在原生协议的基础上添加了一些额外的头信息,比如service name,magic number等。

使用dubbo thrift协议同样需要使用thrift的idl compiler编译生成相应的JAVA代码,后续版本中会在这方面做一些增强。

七、缓存

memcached:

基于memcached实现的RPC协议

redis:

基于Redis实现的RPC协议

二、注册中心

一、Multicast

Multicast注册中心不需要启动任何中心节点,只要广播地址一样,就可以互相发现

1、提供方启动时广播自己的地址。

2、消费方启动时广播订阅请求

3、提供方收到订阅请求时,单播自己的地址给订阅者,如果设置了unicast=false,则广播给订阅者

4、消费方收到提供方地址时,连接该地址进行RPC调用。

组播受网络结构限制,只适合小规模应用或开发阶段使用。组播地址段:244.0.0.0 - 239.255.255.255

二、zookeeper

Zookeeper是Apacahe Hadoop的子项目,是一个树型的目录服务,支持变更推送,适合作为Dubbo服务的注册中心,工业强度较高,可用于生产环境,并推荐使用。

流程说明:

服务提供者启动时:向dubbo/com.foo.BarService/providers目录下写入自己的URL地址

服务消费者启动时:订阅/dubbo/com.foo.BarService/providers 目录下的提供者 URL 地址。并向 /dubbo/com.foo.BarService/consumers 目录下写入自己的 URL 地址

监控中心启动时:订阅/dubbo/com.foo.BarService目录下的所有提供者和消费者URL地址

支持以下功能:

当提供者出现断电等异常停机时,注册中心能自动删除提供者信息。

当注册中心重启时,能自动恢复注册数据,以及订阅请求。

当会话过期时,能自动恢复注册数据,以及订阅请求。

当设置 <dubbo:registry check="false" /> 时,记录失败注册和订阅请求,后台定时重试

可通过 <dubbo:registry username="admin" password="1234" /> 设置 zookeeper 登录信息

可通过 <dubbo:registry group="dubbo" /> 设置 zookeeper 的根节点,不设置将使用无根树

支持*号通配符 <dubbo:reference group="*" version="*" />,可订阅服务的所有分组和所有版本的提供者

zk挂了会怎么样

启动dubbo时,消费者会从zk拉取注册的生产者的地址接口等数据,缓存在本地。每次调用时,按照本地存储的地址进行调用

注册中心对等集群,任意一台宕掉后,会自动切换到另一台
注册中心全部宕掉,服务提供者和消费者仍可以通过本地缓存通讯
服务提供者无状态,任一台 宕机后,不影响使用
服务提供者全部宕机,服务消费者会无法使用,并无限次重连等待服务者恢复

分布式与数据复制

Zookeeper作为一个集群提供一致的数据服务,自然,它要在所有机器间做数据复制。数据复制的好处:

1、 容错
一个节点出错,不致于让整个系统停止工作,别的节点可以接管它的工作;

2、提高系统的扩展能力
把负载分布到多个节点上,或者增加节点来提高系统的负载能力;

3、提高性能
让客户端本地访问就近的节点,提高用户访问速度。

Zookeeper中的角色主要有以下三类,如下表所示:

服务内如何获取dubbo接口的提供者列表_序列化

一个Server是如何知道其它的Server?

在ZooKeeper集群中,Server的信息都在zoo.conf配置文件中,根据配置文件的信息就可以知道其它Server的信息。

ZooKeeper服务器有哪几种状态?(选主相关的状态)

LOOKING:寻找leader状态
LEADING:领导状态(节点为leader)
FOLLOWING:跟随者状态
OBSERVING:观察者状态(此状态不参与选举)

成为Leader的必要条件?

Leader要具有最高的zxid;集群中大多数的机器(至少n/2+1)得到响应并follow选出的Leader

如果所有zxid都相同(例如: 刚初始化时),此时有可能不能形成n/2+1个Server,怎么办?
ZooKeeper中每一个Server都有一个ID,这个ID是不重复的,如果遇到这样的情况时,ZooKeeper就推荐ID最大的哪个Server作为Leader。

lookForLeader函数什么时候被调用?
当Server的状态为LOOKING时,lookForLeader就会被调用。具体参见QuorumPeer类的run方法。

ZooKeeper中Leader怎么知道Fllower还存活,Fllower怎么知道Leader还存活?
Leader定时向Fllower发ping消息,Fllower定时向Leader发ping消息,当发现Leader无法ping通时,就改变自己的状态(LOOKING),发起新的一轮选举。

三、Redis

基于Redis实现的注册中心

使用Redis的Key/Map结构存储数据结构:

主Key为服务名和类型

Map中的Key为URL地址

Map中的value为过期时间,用于判断脏数据,脏数据由监控中心删除

使用Redis的Publish/Subscribe事件通知数据变更:

通过事件的值区分事件类型:register,unregister,subscribe,unregister事件

普通消费者直接订阅指定服务提供者的Key,只会收到指定服务的register,unregister事件

监控中心通过psubscribe功能订阅/dubbo/*, 会收到所有服务的所有变更事件

调用过程:

1服务提供方启动时,向Key:/dubbo/com.foo.BarService/providers 下,添加当前提供者的地址

2并向 Channel:/dubbo/com.foo.BarService/providers 发送 register 事件
3服务消费方启动时,从 Channel:/dubbo/com.foo.BarService/providers 订阅 register 和 unregister 事件
4并向 Key:/dubbo/com.foo.BarService/providers 下,添加当前消费者的地址
5服务消费方收到 register 和 unregister 事件后,从 Key:/dubbo/com.foo.BarService/providers 下获取提供者地址列表
6服务监控中心启动时,从 Channel:/dubbo/* 订阅 register 和 unregister,以及 subscribe 和unsubsribe事件
7服务监控中心收到 register 和 unregister 事件后,从 Key:/dubbo/com.foo.BarService/providers 下获取提供者地址列表
8服务监控中心收到 subscribe 和 unsubsribe 事件后,从 Key:/dubbo/com.foo.BarService/consumers 下获取消费者地址列表

四、Simple

Simple注册中心本身就是一个普通的Dubbo服务,可以减少第三方依赖,使整体通讯方式一致。

三、集群容错

Failover Cluster

失败自动切换,当出现失败,重试其它服务器,通常用于读操作,但重试会带来更长延迟。可通过retries="2"来设置重试次数(不含第一次)

重试次数配置如下:

<dubbo:service retries="2" /> 或<dubbo:reference retries=“2” />或``

<dubbo:reference>
		<dubbo:method name="findFoo" retries="2" />
	</dubbo:reference>

Failfast Cluster
快速失败,只发起一次调用,失败立即报错,通常用于非幂等性的写操作,比如新增记录。
Failsafe Cluster
失败安全,出现异常时,直接忽略 ,通常用于写入审计日志等操作。
Failback Cluster
失败自动恢复,后台记录失败请求,定时重发,通常用于消息通知操作。
Forking Cluster
并行调用多个服务器,只要一个成功即返回。通常用于实时性要求较高的读操作,但需要浪费更多服务资源。可通过fork="2"来设置最大并行数。
Broadcast Cluster
广播调用所有提供者,逐个调用,任意一台报错则报错。通常用于通知所有提供者更新缓存或日志等本地资源信息。

扩展

dubbo过滤器(拦截器)Filter的使用及应用场景

Dubbo Filter是为了开发者在未全局方法调用时统一添加额外参数时使用到的。
主要场景有:
1、传递线程上下文信息
2、方法上的共同参数统一传递,避免每次方法调用时去设置

比如:一个web应用有会话信息,这个web应用需要调用另外一个dubbo服务(这里是内部管理比较紧密的项目),这时提供dubbo服务这个项目,想要获取当前调用的用户会话信息,方便记录日志,这个时候使用Dubbo Filter就非常合适。加上spring aop配合使用,将会非常简单。

dubbo负载均衡策略

负载均衡策略及优缺点

Dubbo 负载均衡策略提供下列四种方式:

Random LoadBalance 随机,按权重设置随机概率。 Dubbo的默认负载均衡策略

在一个截面上碰撞的概率高,但调用量越大分布越均匀,而且按概率使用权重后也比较均匀,有利于动态调整提供者权重。

RoundRobin LoadBalance 轮循,按公约后的权重设置轮循比率。

存在慢的提供者累积请求问题,比如:第二台机器很慢,但没挂,当请求调到第二台时就卡在那,久而久之,所有请求都卡在调到第二台上。

LeastActive LoadBalance 最少活跃调用数,相同活跃数的随机,活跃数指调用前后计数差。

使慢的提供者收到更少请求,因为越慢的提供者的调用前后计数差会越大。

ConsistentHash LoadBalance 一致性Hash,相同参数的请求总是发到同一提供者。

当某一台提供者挂时,原本发往该提供者的请求,基于虚拟节点,平摊到其它提供者,不会引起剧烈变动。