1.注册中心
1.1 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 地址。
支持以下功能
- 当提供者出现断电等异常停机时,注册中心能自动删除提供者信息
- 当注册中心重启时,能自动恢复注册数据,以及订阅请求
- 当会话过期时,能自动恢复注册数据,以及订阅请求
- 当设置 时,记录失败注册和订阅请求,后台定时重试
- 可通过 设置zookeeper 登录信息
- 可通过 设置 zookeeper 的根节点,不设置将使用无根树
- 支持 * 号通配符 ,可订阅服务的所有分组和所有版本的提供者
使用
首先在provider和consumer中增加zookeeper客户端jar包依赖
<dependency>
<groupId>org.apache.zookeeper</groupId>
<artifactId>zookeeper</artifactId>
<version>3.3.3</version>
</dependency>
Dubbo支持zkclient和curator两种Zookeeper客户端实现
单机配置
<dubbo:registry address="zookeeper://10.20.153.10:2181" />
集群配置
<dubbo:registry protocol="zookeeper" address="10.20.153.10:2181,10.20.153.11:2181,10.2
0.153.12:2181" />
同一Zookeeper分成多组注册中心
<dubbo:registry id="chinaRegistry" protocol="zookeeper" address="10.20.153.10:2181" group="china" />
<dubbo:registry id="intlRegistry" protocol="zookeeper" address="10.20.153.10:2181" group="intl" />
1.2 Muticast
Multicast 注册中心不需要启动任何中心节点,只要广播地址一样,就可以互相发现。
- 提供方启动时广播自己的地址
- 消费方启动时广播订阅请求
- 提供方收到订阅请求时,单播自己的地址给订阅者,如果设置了 unicast=false ,则广播给订阅者
- 消费方收到提供方地址时,连接该地址进行 RPC 调用。
组播受网络结构限制,只适合小规模应用或开发阶段使用。组播地址段: 224.0.0.0-239.255.255.255
配置
<dubbo:registry address="multicast://224.5.6.7:1234" />
1.3 Redis
基于Redis实现的注册中心
使用Redis的Key/Map结构存储数据结构
- 主Key为服务名和类型
- Map中的Key为URL地址
- Map中的Value为过期时间,用于判断脏数据,脏数据由监控中心删除
使用Redis的Publish/Subscribe时间通知数据变更
- 通过事件的值区分事件类型:register,unregister,subscribe,unsubscribe
- 普通消费者直接订阅指定服务提供者的Key,只会收到指定服务的register,unregister 事件
- 监控中心通过psubscribe功能订阅/dubbo/*,会收到所有服务的所有变更事件
配置使用
<dubbo:registry address="redis://10.20.153.10:6379" />
或
<dubbo:registry protocol="redis" address="10.20.153.10:6379,10.20.153.11:6379,10.20.15
3.12:6379" />
注意:阿里内部并没有使用过redis注册中心,Redis注册中心没有在阿里内部长时间运行的可靠性保障,此Redis桥接实现只为开源版本提供,其可靠性依赖于Redis本身的可靠性
1.4 Simple
Simple注册中心本身就是一个普通的Dubbo服务,可以减少第三方依赖,使整体通讯方式一致 但是只简单实现,不支持集群,可作自定义注册中心的参考,不适合生产环境
2.协议
2.1 dubbo
Dubbo缺省协议采用单一长连接和NIO异步通讯,适合于小数据量大并发的服务调用,以及服务消费者机器数远大于服务提供者机器数的情况。反之,Dubbo缺省协议不适合传送大数据量的服务,比如文件、视频等,除非请求量很低。
- Transporter:mina,netty,grizzy
- Serialization:dubbo,hession2,java,json
- Dispatcher:all,direct,message,excution,connection
- ThreadPool:fixed,cached
2.1.1 特性
- 连接个数:单连接
- 连接方式:长连接
- 传输协议:TCP
- 传输方式:NIO异步传输
- 序列化:Hessian二进制序列化
- 使用范围:传入传出参数数据包较小(建议小于100K),消费者比提供者个数多,单一消费者无法压满提供者,尽量不要用dubbo协议传输大文件或超大字符串
- 适用场景:常规远程方法调用
2.2.2 约束
- 参数及返回值需实现Serializable接口
- 参数及返回值不能自定义实现List,Map,Number,Number,Date,Calender等接口,只能用JDK自带的实现,因为Hessian会做特殊处理,自定义实现类中的属性值都会丢失
- Hessian序列化,只传成员属性值和值的类型,不传方法或静态变量
2.2.3 配置
- 配置协议
<bubbo:protocol name="dubbo" port="20880">
- 配置多端口
<dubbo:protocol id="dubbo1" name="dubbo" port="20880" />
<dubbo:protocol id="dubbo2" name="dubbo" port="20881" />
- 协议配置选项
<dubbo:protocol name=“dubbo” port=“9090” server=“netty” client=“netty” codec=“dubbo” s
erialization=“hessian2” charset=“UTF-8” threadpool=“fixed” threads=“100” queues=“0” io
threads=“9” buffer=“8192” accepts=“1000” payload=“8388608” />
- 多连接配置
Dubbo协议缺省每台服务每提供者每消费者使用单一长连接,如果数据量较大,可以使用多个连接
<dubbo:protocol name="dubbo" connections="2" />
表示该服务使用独立两条长连接。
为防止被大量连接撑挂,可在服务提供方限制大接收连接数,以实现服务提供自我保护
<dubbo:protocol name="dubbo" accepts="1000" />
2.1.4 为什么使用单一长连接
因为服务的现状大都是服务提供者少,通常只有几台机器,而服务的消费者多,可能整个网站都在访问该服务,比如 Morgan 的提供者只有 6 台提供者,却有上百台消费者,每天有 1.5亿次调用,如果采用常规的 hessian 服务,服务提供者很容易就被压跨,通过单一连接,保证单一消费者不会压死提供者,长连接,减少连接握手验证等,并使用异步 IO,复用线程池,防止 C10K 问题。
2.2 rmi
特性
- 连接个数:多连接
- 连接方式:短连接
- 传输协议:TCP
- 传输方式:同步传输
- 序列化:java标准二进制序列化
- 适应范围:传入传出参数数据包大小混合,消费者与提供者个数差不多,可传文件
- 适用场景:常规远程服务方法调用,与原生RMI服务互操作
2.3 hessian
特性:
- 连接个数:多连接
- 连接方式:长连接
- 传输协议:HTTP
- 传输方式:同步传输
- 序列化:Hessian二进制序列化
- 适应范围:传入传出参数数据包较大,提供者比消费者个数多,提供者压力较大,可传文件
- 适用场景:页面船速,文件传输,或与原生hessian服务互操作
2.4 http
特性:
- 连接个数:多连接
- 连接方式:短连接
- 传输协议:HTTP
- 传输方式:同步传输
- 序列化:表单序列化
- 适用范围:传入传出参数数据包大小混合,提供者比消费者个数多,可用浏览器查看,可用表单或URL传入参数,暂不支持传文件
- 适应场景:需同时给应用程序和浏览器JS使用的服务
2.5 webservice
基于WebService的远程调用协议,基于Apache CXF的frontend-simple和transports-http实现可以和原生WebService服务互操作:
- 提供者用Dubbo的WebService协议暴露服务,消费者直接用标准WebService接口调用
- 或者提供方用标准WebService暴露服务,消费方用Dubbo的WebService协议调用
特性:
- 连接个数:多连接
- 连接方式:短连接
- 传输协议:HTTP
- 传输方式:同步传输
- 序列化:SOAP文本序列化
- 适用场景:系统机场,跨语言调用
2.6 thrift
了解就好,不作过多介绍
2.7 memcached
了解就好,不作过多介绍
2.8 redis
了解就好,不作过多介绍
3.集群容错
当集群调用失败时,dubbo提供了多种容错方案,缺省为failover重试
各节点关系:
- Invoker是Provider的一个可调用的Service的抽象,Invoker封装了Provider地址及多个接口信息
- Directory代表了多个Invoker,可以把它看成List,但与List不同的是,它的值可能是动态变化的,比如注册中心推送变更
- Cluster将Directory中的多个Invoker伪装成一个Invoker,对上层透明,伪装过程包含了容错逻辑,调用失败后,重试另一个
- Router负责从多个Invoker中按路由规则选出子集,比如读写分离,应用隔离等
- LoadBalance负责从多个Invoker中选出具体的一个用于本次调用,选的过程包含了负载均衡算法,调用失败后,需要重选
容错模式:
- Failover Cluster
- 失败自动切换,当出现失败,重试其他服务器
- 通常用于读操作,但重试会带来更长延迟
- 可通过retries=”2”来设置重试次数(不含第一次)
配置如下
<dubbo:service retries="2" />
或
<dubbo:reference retries="2" />
- Failfast Cluster
- 快速失败,只发起一次调用,失败立即报错
- 通常用于非幂等性的写操作,比如新增记录
- Failsafe Cluster
- 失败安全,出现异常时,直接忽略
- 通常用于写入审计日志等操作
- Failback Cluster
- 失败自动回复,后台记录失败请求,定时重发
- 通常用于消息通知操作
- Forking Cluster
- 并行调用多个服务器,只要一个成功即返回
- 通常用于实时性要求较高的读操作,但需要浪费更多服务资源
- 可通过forks=”2”来设置最大并行数
- Broadcast Cluster
- 广播调用所有提供者,逐个调用,任意一台报错则报错
- 通常用于通知所有提供者更新缓存或日志等本地资源信息
4.负载均衡
Dubbo提供了多种负载策略,缺省为random随机调用
4.1 负载均衡策略
- Random LoadBalance
- 随机,按权重设置随机概率
- 在一个截面上碰撞的概率高,但调用越大分布越均匀,而且按概率使用权重后也比较均匀,有利于动态调整提供者权重
- RoundRobin LoadBalance
- 轮询,按公约后的权重设置轮询比率
- 存在慢的提供者请求的问题,比如:第二胎机器很慢,但没挂,当请求调到第二台时就卡在那,久而久之,所有请求都卡在调到第二台上
- LeastActive LoadBalance
- 最少活跃调用数,相同活跃数的随机,活跃数指调用前后计数差
- 使慢的提供者收到更少请求,因为越慢的提供者的调用前后计数差会越大
- ConsistentHash LoadBalance
- 一致性Hash,相同参数的请求总是发到同一提供者
- 当某一台提供者挂时,原本该发往该提供者的请求,基于虚拟节点,平摊到其他提供者,不会引起剧烈变动
- 缺省只对第一个参数Hash,入伙要修改,请配置
<dubbo:paramter key="hash.arguments" value="0,1">
- 缺省用160份虚拟节点,如果修改请配置
<dubbo:parameter key="hash.nodes" value="320">
- 算法参见:http://en.wikipedia.org/wiki/Consistent_hashing
4.2 配置方式
- 服务级别
服务端
<dubbo:service interface="..." loadbalance="roundrobin" />
客户端
<dubbo:reference interface="..." loadbalance="roundrobin" />
- 方法级别
服务端
<dubbo:service interface="...">
<dubbo:method name="" loadbalance="roundrobin">
<dubbo:service>
客户端
<dubbo:reference interface="...">
<dubbo:method name="" loadbalance="roundrobin">
<dubbo:reference>