开发者学堂课程【基于 Zookeeper、Dubbo 构建互联网分布式基础架构:duboo 相关内容介绍(2)】学习笔记,与课程紧密联系,让用户快速学习知识。
课程地址:https://developer.aliyun.com/learning/course/635/detail/10169
duboo 相关内容介绍(2)
内容介绍:
一、示例
二、Schema 配置参考手册
三、协议参考手册
四、注册中心参考手册
一、示例
1. 启动时检查
Dubbo 缺省会在启动时检查依赖的服务是否可用,不可用时会抛出异常,阻止 Spring 初始化完成,以便上线时,能及早发现问题,默认 check="true"。
可以通过 check="false" 关闭检查,比如,测试时,有些服务不关心,或者出现了循环依赖,必须有一方先启动。
另外,如果你的 Spring 容器是懒加载的,或者通过 API 编程延迟引用服务,请关闭 check,否则服务临时不可用时,会抛出异常,拿到 null 引用,如果 check="false",总是会返回引用,当服务恢复时,能自动连上。
示例
通过 spring 配置文件
关闭某个服务的启动时检查 (没有提供者时报错)
关闭所有服务的启动时检查 (没有提供者时报错):
关闭注册中心启动时检查 (注册订阅失败时报错):
通过 dubbo.properties
dubbo.reference.com.foo.BarService.check=false
dubbo.reference.check=false
dubbo.consumer.check=false
dubbo.registry.check=false
通过 -D 参数
java -Ddubbo.reference.com.foo.BarService.check=false
java -Ddubbo.reference.check=false
java -Ddubbo.consumer.check=false
java -Ddubbo.registry.check=false
配置的含义
dubbo.reference.check=false,强制改变所有 reference 的 check 值,就算配置中有声明,也会被覆盖。
dubbo.consumer.check=false,是设置 check 的缺省值,如果配置中有显式的声明,如:,不会受影响。
dubbo.registry.check=false,前面两个都是指订阅成功,但提供者列表是否为空是否报错,如果注册订阅失败时,也允许启动,需使用此选项,将在后台定时重试。
2. 集群容错
在集群调用失败时,Dubbo 提供了多种容错方案,缺省为 failover 重试。
各节点关系:
(1)这里的 Invoker 是 Provider 的一个可调用 Service 的抽象,Invoker 封装了 Provider 地址及 Service 接口信息
(2)Directory 代表多个 Invoker,
可以把它看成 List ,但与 List 不同的是,它的值可能是动态变化的,比如注册中心推送变更
(3)Cluster 将 Directory 中的多个 Invoker 伪装成一个 Invoker,对上层透明,伪装过程包含了容错逻辑,调用失败后,重试另一个
(4)Router 负责从多个 Invoker 中按路由规则选出子集,比如读写分离,应用隔离等
(5)LoadBalance 负责从多个 Invoker 中选出具体的一个用于本次调用,选的过程包含了负载均衡算法,调用失败后,需要重选
集群容错模式
可以自行扩展集群容错策略,
参见:集群扩展
Failover Cluster
失败自动切换,当出现失败,重试其它服务器。通常用于读操作,但重试会带来更长延迟。可通过 retries="2" 来设置重试次数(不含第一次)。
快速失败,只发起一次调用,失败立即报错。通常用于非幂等性的写操作,比如新增记录。
Failsafe Cluster
失败安全,出现异常时,直接忽略。通常用于写入审计日志等操作。
Failback Cluster
失败自动恢复,后台记录失败请求,定时重发。通常用于消息通知操作。
Forking Cluster
并行调用多个服务器,只要一个成功即返回。通常用于实时性要求较高的读操作,但需要浪费更多服务资源。可通过 forks="2" 来设置最大并行数。
Broadcast Cluster
广播调用所有提供者,逐个调用,任意一台报错则报错。通常用于通知所有提供者更新缓存或日志等本地资源信息。
集群模式配置
按照以下示例在服务提供方和消费方配置集群模式
或
3. 负载均衡
在集群负载均衡时,Dubbo 提供了多种均衡策略,缺省为 random 随机调用。
可以自行扩展负载均衡策略,参见:负载均衡扩展
负载均衡策略
Random LoadBalance
(1)随机,按权重设置随机概率。
(2)在一个截面上碰撞的概率高,但调用量越大分布越均匀,而且按概率使用权重后也比较均匀,有利于动态调整提供者权重。
RoundRobin LoadBalance
(1)轮询,按公约后的权重设置轮询比率。
(2)存在慢的提供者累积请求的问题,比如:第二台机器很慢,但没挂,当请求调到第二台时就卡在那,久而久之,所有请求都卡在调到第二台上。
LeastActive LoadBalance
(1)最少活跃调用数,相同活跃数的随机,活跃数指调用前后计数差。
(2)使慢的提供者收到更少请求,因为越慢的提供者的调用前后计数差会越大。
ConsistentHash LoadBalance
(1)一致性 Hash,相同参数的请求总是发到同一提供者。
(2)当某一台提供者挂时,原本发往该提供者的请求,基于虚拟节点,平摊到其它提供者,不会引起剧烈变动。
(3)算法参见:
http://en.wikipedia.org/wiki/Consistent_hashing
(4)缺省只对第一个参数 Hash,如果要修改,请配置
缺省用 160 份虚拟节点,如果要修改,请配置
配置
服务端服务级别
客户端服务级别
服务端方法级别
客户端方法级别
4. 线性模型
如果事件处理的逻辑能迅速完成,并且不会发起新的 IO 请求,比如只是在内存中记个标识,则直接在 IO 线程上处理更快,因为减少了线程池调度。
但如果事件处理逻辑较慢,或者需要发起新的 IO 请求,比如需要查询数据库,则必须派发到线程池,否则 IO 线程阻塞,将导致不能接收其它请求。
如果用 IO 线程处理事件,又在事件处理过程中发起新的 IO 请求,比如在连接事件中发起登录请求,会报“可能引发死锁”异常,但不会真死锁。
因此,需要通过不同的派发策略和不同的线程池配置的组合来应对不同的场景:
ction 在 IO 线程上,将连接断开事件放入队列,有序逐个执行,其它消息派发到线程池。
5.直连提供者
在开发及测试环境下,经常需要绕过注册中心,只测试指定服务提供者,这时候可能需要点对点直连,点对点直连方式,将以服务接口为单位,忽略注册中心的提供者列表,A 接口配置点对点,不影响 B 接口从注册中心获取列表。
通过 XML 配置
如果是线上需求需要点对点,可在 中配置 url 指向提供者,将绕过注册中心,多个地址用分号隔开,配置如下:
通过 -D 参数指定
在 JVM 启动参数中加入-D参数映射服务地址,如:
java -Dcom.alibaba.xxx.XxxService=dubbo://localhost:20890
6.只订阅
为方便开发测试,经常会在线下共用一个所有服务可用的注册中心,这时,如果一个正在开发中的服务提供者注册,可能会影响消费者不能正常运行。
可以让服务提供者开发方,只订阅服务(开发的服务可能依赖其它服务),而不注册正在开发的服务,通过直连测试正在开发的服务。
7.静态服务
有时候希望人工管理服务提供者的上线和下线,此时需将注册中心标识为非动态管理模式。
或者
服务提供者初次注册时为禁用状态,需人工启用。断线时,将不会被自动删除,需人工禁用。
如果是一个第三方服务提供者,比如 memcached,可以直接向注册中心写入提供者地址信息,消费者正常使用
8.多协议
Dubbo 允许配置多协议,在不同服务上支持不同协议或者同一服务上同时支持多种协议。
不同服务不同协议
不同服务在性能上适用不同协议进行传输,比如大数据用短连接协议,小数据大并发用长连接协议
多协议暴露服务
需要与 http 客户端相互操作
9.多注册中心
Dubbo 支持同一服务向多注册中心同时注册,或者不同服务分别注册到不同的注册中心上去,甚至可以同时引用注册在不同注册中心上的同名服务。另外,注册中心是支持自定义扩展的 1。
多注册中心注册
比如:中文站有些服务来不及在青岛部署,只在杭州部署,而青岛的其它应用需要引用此服务,就可以将服务同时注册到两个注册中心。
不同服务使用不同注册中心
比如:
CRM 有些服务是专门为国际站设计的,有些服务是专门为中文站设计的。
CRM 需同时调用中文站和国际站的 PC2 服务,PC2 在中文站和国际站均有部署,接口及版本号都一样,但连的数据库不一样。
如果只是测试环境临时需要连接两个不同注册中心,使用竖号分隔多个不同注册中心地址:
10.服务分组
当一个接口有多种实现时,可以用 group 区分。
服务
2.2.0 以上版本支持,总是只调一个可用组的实现
11.多版本
当一个接口实现,出现不兼容升级时,可以用版本号过渡,版本号不同的服务相互间不引用。
可以按照以下的步骤进行版本迁移:
(1)在低压力时间段,先升级一半提供者为新版本
(2)再将所有消费者升级为新版本
(3)然后将剩下的一半提供者升级为新版本
老版本服务提供者配置:
新版本服务提供者配置:
iceinterface="com.foo.BarService" version="2.0.0" />
老版本服务消费者配置:
新版本服务消费者配置:
如果不需要区分版本,可以按照以下的方式配置 [^1]:
12.分组聚合
按组合并返回结果,比如菜单服务,接口一样,但有多种实现,用group区分同,现在消费方需从每种group中调用一次并返回结果,合并结束后,这样就可以实现聚合菜单项。
指定合并策略,缺省根据返回值类型自动匹配,如果同一类型有两个合并器时,需指定合并器的名称
指定合并方法,将调用返回结果的指定方法进行合并,合并方法的参数类型必须是返回结果类型本身。
二、Schema 配置参考手册
二、Schema 配置参考手册
所有配置项分为三大类,参见下表中的"作用" 一列。
(1)服务发现:表示该配置项用于服务的注册与发现,目的是让消费方找到提供方。
(2)服务治理:表示该配置项用于治理服务间的关系,或为开发测试提供便利条件。
(3)性能调优:表示该配置项用于调优性能,不同的选项对性能会产生影响。
(4)所有配置最终都将转换为 URL 3 表示,并由服务提供方生成,经注册中心传递给消费方,各属性对应 URL 的参数,参见配置项一览表中的 “对应URL参数” 列。
三、协议参考手册
三、协议参考手册
1. dubbo://
Dubbo 缺省协议采用单一长连接和 NIO 异步通讯,适合于小数据量大并发的服务调用,以及服务消费者机器数远大于服务提供者机器数的情况。
反之,Dubbo 缺省协议不适合传送大数据量的服务,比如传文件,传视频等,除非请求量很低。
特性
缺省协议,使用基于
netty 3.2.5.Final 和 hessian2 3.2.1-fixed-2(Alibaba embed version) 的 tbremoting
交互。
(1)连接个数:单连接
(2)连接方式:长连接
(3)传输协议:TCP
(4)传输方式:NIO 异步传输
(5)序列化:Hessian 二进制序列化
(6)适用范围:传入传出参数数据包较小(建议小于100K),消费者比提供者个数多,单一消费者无法压满提供者,尽量不要用 dubbo 协议传输大文件或超大字符串。
(7)适用场景:常规远程服务方法调用
配置
配置协议
设置默认协议:
设置服务协议:
多端口:
多连接配置:
Dubbo 协议缺省每服务每提供者每消费者使用单一长连接,如果数据量较大,可以使用多个连接。
(1)
或
表示该服务使用 JVM 共享长连接。缺省
(2)
或
表示该服务使用独立长连接。
(3)
或
表示该服务使用独立两条长连接。
为防止被大量连接撑挂,可在服务提供方限制大接收连接数,以实现服务提供方自我保护。
常见问题
为什么要消费者比提供者个数多?
因 dubbo 协议采用单一长连接,假设网络为千兆网卡 3,根据测试经验数据每条连接最多只能压满 7MByte(不同的环境可能不一样,供参考),理论上 1 个服务提供者需要 20 个服务消费者才能压满网卡。
为什么不能传大包?
因 dubbo 协议采用单一长连接,如果每次请求的数据包大小为 500KByte,假设网络为千兆网卡 3,每条连接最大 7MByte(不同的环境可能不一样,供参考),单个服务提供者的 TPS(每秒处理事务数)最大为:128MByte / 500KByte = 262。单个消费者调用单个服务提供者的 TPS(每秒处理事务数)最大为:7MByte / 500KByte = 14。如果能接受,可以考虑使用,否则网络将成为瓶颈。
为什么采用异步单一长连接?
因为服务的现状大都是服务提供者少,通常只有几台机器,而服务的消费者多,可能整个网站都在访问该服务,比如 Morgan 的提供者只有 6 台提供者,却有上百台消费者,每天有 1.5 亿次调用,如果采用常规的 hessian 服务,服务提供者很容易就被压跨,通过单一连接,保证单一消费者不会压死提供者,长连接,减少连接握手验证等,并使用异步 IO,复用线程池,防止 C10K 问题。
四、注册中心参考手册
四、注册中心参考手册
1.Zookeeper 注册中心
Zookeeper 是 Apache Hadoop 的子项目,是一个树型的目录服务,支持变更推送,适合作为 Dubbo 服务的注册中心,工业强度较高,可用于生产环境,并推荐使用。
流程说明:
(1)服务提供者启动时:
向 /dubbo/com.foo.BarService/providers 目录下写入自己的 URL 地址
(2)服务消费者启动时:
订阅
/dubbo/com.foo.BarService/providers
目录下的提供者 URL 地址。并向 /dubbo/com.foo.BarService/consumers
目录下写入自己的 URL 地址
(3)监控中心启动时: 订阅
/dubbo/com.foo.BarService
目录下的所有提供者和消费者 URL 地址。
支持以下功能:
(1)当提供者出现断电等异常停机时,注册中心能自动删除提供者信息
(2)当注册中心重启时,能自动恢复注册数据,以及订阅请求
(3)当会话过期时,能自动恢复注册数据,以及订阅请求
(4)当设置
时,记录失败注册和订阅请求,后台定时重试
(5)可通过
设置 zookeeper 登录信息
(6)可通过
设置 zookeeper 的根节点,不配置将使用默认的根节点。
(7)支持 * 号通配符
,可订阅服务的所有分组和所有版本的提供者
使用 zkclient 客户端
从 2.2.0 版本开始缺省为 zkclient 实现,以提升 zookeeper 客户端的健壮性。zkclient 是 Datameer 开源的一个 Zookeeper 客户端实现。
缺省配置:
或
dubbo.registry.client=zkclient
或
zookeeper://10.20.153.10:2181?client=zkclient
如果需要改为 curator 实现,请配置:
或:
dubbo.registry.client=curator
或:
zookeeper://10.20.153.10:2181?client=curator
zookeeper 安装
安装方式参见:
Zookeeper安装手册,只需搭一个原生的 Zookeeper 服务器,并将 Quick Start 中 Provider 和 Consumer 里的 conf/dubbo.properties 中的 dubbo.registry.address 的值改为 zookeeper://127.0.0.1:2181 即可使用。
可靠性声明
阿里内部并没有采用 Zookeeper 做为注册中心,而是使用自己实现的基于数据库的注册中心,即:Zookeeper 注册中心并没有在阿里内部长时间运行的可靠性保障,此 Zookeeper 桥接实现只为开源版本提供,其可靠性依赖于 Zookeeper 本身的可靠性。
兼容性声明
因 2.0.8 最初设计的 zookeeper 存储结构不能扩充不同类型的数据,2.0.9 版本做了调整,所以不兼容,需全部改用 2.0.9 版本才行,以后的版本会保持兼容 2.0.9。2.2.0 版本改为基于 zkclient 实现,需增加 zkclient 的依赖包,2.3.0 版本增加了基于 curator 的实现,作为可选实现策略。