启动服务检查
Dubbo 缺省会在启动时检查依赖的服务是否可用,不可用时会抛出异常,阻止 Spring 初始化完成,以便上线时,能及早发现问题,默认
check="true"
。
dubbo:reference
check
属性- true
- 表示启动的时候检查依赖的服务是否正常
- false
- 关闭检查
- 当服务出现循环依赖时
- 当有些服务不关心时
- true
所有服务的启动时检查提供者
dubbo:consumer
check
属性- true
- false
- 没有服务提供者时报错
所有服务的启动时检查消费者
- dubbo:provider
check
属性- false
- 没有服务消费者失败报错
- false
注册中心启动时检查注册订阅是否失败
dubbo:registry
check
属性- false
- 注册订阅失败报错
- false
多协议支持
- dobbo支持的协议
- dubbo://(TCP)
- 介绍
- Dubbo缺省协议采用单一长连接和NIO异步通讯,适合于小数据量大并发的服务调用,以及服务消费者机器数远大于服务提供者机器数的情况。
- 反之,Dubbo 缺省协议不适合传送大数据量的服务,比如传文件,传视频等,除非请求量很低。
- 缺省协议,使用基于 mina
1.1.7
和 hessian3.2.1
的 tbremoting 交互。
- 约束
- 参数及返回值需实现
Serializable
接口 - 参数及返回值不能自定义实现
List
,Map
,Number
,Date
,Calendar
等接口,只能用 JDK 自带的实现,因为 hessian 会做特殊处理,自定义实现类中的属性值都会丢失。
- 参数及返回值需实现
- 常见问题
- 为什么消费者比提供者个数多
- 因dubbo协议采用单一长连接,假设网络为千兆网卡,根据测试经验数据每条连接最多只能压满7MByte(不同的环境可能不一样,供参考),理论上1个服务提供者需要20个服务消费者才能压满网卡。
- 为什么不能传大包
- 因dubbo协议采用单一长连接,如果每次请求的数据包大小为500KByte,假设网络为千兆网卡,每条连接最大7MByte(不同环境可能不一样,供参考),单个服务提供者的TPS(每秒处理事务数)最大为:128MByte/500KByte=262。单个消费者调用单个服务提供的TPS(每秒处理事务数)最大为7MByte/500KByte=14。如果能接受,可以考虑使用,否则网络将成为瓶颈。
- 为什么采用异步单一长连接
- 因为服务的现状大都是服务提供者少,通常只有机台机器,而服务的消费者多,可能整个网站都在访问该服务,比如Morgan的提供者只有6台,却有上百台消费者,每天有1.5亿次调用,如果采用常规的hessian服务,服务提供者很容易就被压垮,通过单一长连接,保证单一消费者不会压死提供者,长连接,减少连接握手验证等,并使用异步IO,复用线程池,防止C10K问题(C10K 就是 Client 10000 问题,即「在同时连接到服务器的客户端数量超过 10000 个的环境中,即便硬件性能足够, 依然无法正常提供服务」,简而言之,就是单机1万个并发连接问题。)。
- 为什么消费者比提供者个数多
- 介绍
- rmi://(TCP)
- hessian://(http)
- 介绍
- Hessian 1 协议用于集成 Hessian 的服务,Hessian 底层采用 Http 通讯,采用 Servlet 暴露服务,Dubbo 缺省内嵌 Jetty 作为服务器实现。
- Dubbo 的 Hessian 协议可以和原生 Hessian 服务互操作,即:
- 提供者用 Dubbo 的 Hessian 协议暴露服务,消费者直接用标准 Hessian 接口调用
- 或者提供方用标准 Hessian 暴露服务,消费方用 Dubbo 的 Hessian 协议调用。
- 介绍
- webservice://(http)
- http://(http)
- thrift://
- memcached://
- redis://
- dubbo://(TCP)
- 改造协议
- 支持多协议
协议对比
协议 | 连接个数 | 连接方式 | 传输协议 | 传输方式 | 序列化 | 适用范围 | 适用场景 |
---|---|---|---|---|---|---|---|
dubbo:// | 单连接 | 长连接 | TCP | NIO异步传输 | Hessian二进制序列化 | 数据包较小(建议小于100K),消费者比提供者个数多,单一消费者无法压满提供者,不要传输大文件或超大字符串 | 常规远程服务方法调用 |
rmi:// | 多连接 | 短连接 | TCP | 同步传输 | Java标准二进制序列化 | 数据包大小混合,消费者与提供者个数差不多,可传文件 | |
hessian:// | 多连接 | 短连接 | HTTP | 同步传输 | Hessian二进制序列化 | 数据包较大,提供者比消费者个数多,提供者压力较大,可传文件 | 页面传输,文件传输,或与原生hessian服务互操作 |
webservice:// | 多连接 | 短连接 | HTTP | 同步传输 | SOAP文本序列化 | 系统集成,跨语言调用 | |
http:// | 多连接 | 短连接 | HTTP | 同步传输 | 表单序列化 | 数据包大小混合,提供者比消费者个数多,可用浏览器查看,可用表单或URL传入参数,暂不支持传文件 | 需同时给应用程序和浏览器JS使用的服务 |
代码演示(hessian)
提供方增加maven依赖
1 | <dependency> |
提供方修改配置
1 | <dubbo:protocol name="hessian" port="8090" server="jetty"/> |
提供方运行
控制台会输出
1 | [com.alibaba.dubbo.config.AbstractConfig] - [DUBBO] Export dubbo service com.bai.dubbo.order.IOrderService to url hessian://... |
消费方修改配置
1 | <dubbo:protocol name="hessian"/> |
或者
1 | <dubbo:reference ... protocol="hessian"/> |
消费方运行
会提示成功
Ps:Maven的SNAPSHOT版本deploy后会直接替换仓库中的版本。release则不会。
多注册中心
1 | <dubbo:registry id="zkOne" protocol="zookeeper" address=""/> |
或
1 | <dubbo:service registry="zkOne" ... /> |
dubbo目前只支持Java
多版本支持
对接口做版本控制,如一个接口升级后需要兼容。
1 | <!--提供方--> |
1 | <!--消费方--> |
发布服务时生成的URL中如没有版本号,那就是未采用版本控制。
异步调用
修改配置文件
1 | <!--消费方--> |
hessian协议不支持,支持dubbo协议
消费方改造
1 | import java.util.concurrent; |
主机绑定
1 | /** |
dubbo服务只订阅
所有的服务都只共用一个注册中心,其中一个服务正在开发,有问题,但注册到注册中心了。就会影响消费者不能正常运行。
需要连注册中心使用服务,但又不能注册该服务。
只订阅服务,不提供服务。
1 | <dubbo:registry register="false" .../> |
dubbo服务只注册
有两个注册中心,服务只在其中一个注册中心部署,另外一个注册中心没有部署时,两个注册中心的其它服务都要依赖此服务。就需要把服务注册到两个注册中心。
只提供服务,不订阅服务。
1 | <dubbo:registry subscribe="false" .../> |
负载均衡
在集群负载均衡时,Dubbo提供了多种均衡策略,缺省为random随机调用。可自行扩展负载均衡策略。
1 | <dubbo:service interface="" loadbalance="roundrobin"/> |
Random LoadBalance
- 随机,按权重设置随机概率。
- 在一个截面上碰撞的概率高,但调用量越大分布越均匀,而且按概率适用权重后也比较均匀,有利于动态调整提供者权重。
RoundRobin LoadBalance
- 轮循,按公约后的权重设置轮循比率。
- 存在慢的提供者累积请求的问题。
- 第二台机器很慢,但没挂,当请求调到第二台时就卡在那,久而久之,所有请求都卡在调到第二台上。
LeastActive LoadBalance
- 最少活跃调用数,相同活跃数的随机。
- 对于响应时间比较短的服务会优先
- 活跃数指调用前后计数差
- 使慢的提供者收到更少请求
- 越慢的提供者的调用前后计数差会越大
ConsistentHash LoadBalance
- 一致性Hash,相同参数的请求总是发到同一提供者。
- 当某一台提供者挂时,原本发往该提供者的请求,基于虚拟节点,平摊到其它提供者,不会引起剧烈变动。
连接超时Timeout
1 | <!--单位为毫秒(常规5秒左右)--> |
如果消费方和提供方都配置timeout属性,以消费方优先级最高,其次为提供方
集群容错
1 | <dubbo:reference cluster="failfast" .../> |
failover cluster(默认)
失败的时候自动切换并重试其它服务器。
通过retries=2来设置重试次数
failfast cluster
快速失败,只发起一次调用。如果失败了,就失败了,不会重试。
写操作(例如新增记录等非幂等操作)如果重试会造成数据重复。
failfafe cluster
失败安全。出现异常时,直接忽略异常(不会报异常)。
写日志时。无需保证日志一定写成功,但需保证主程序正常运行。
failback cluster
失败自动恢复。后台记录失败请求,定时重发。
消息通知。
forking cluster
并行调用多个服务器,只要一个成功就返回。
只能应用在读请求。
浪费服务器资源。
broadcast cluster
广播调用所有提供者,逐个调用。其中一台报错就会返回异常。
配置优先级
消费方 >
提供方
reference method >
service method >
reference >
service >
consumer >
provider