简介:
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中的角色主要有以下三类,如下表所示:
一个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,相同参数的请求总是发到同一提供者。
当某一台提供者挂时,原本发往该提供者的请求,基于虚拟节点,平摊到其它提供者,不会引起剧烈变动。