如何评估服务的容量
第一步,要将服务现在每天的调用量,响应时间,都统计出来,作为容量规划的参考指标
第二步,在线上,将某台机器的权重一直加大,并在加大的过程中记录响应时间的变化,直到响应时间到达阀值,记录此时的访问量
第三步,再以此访问量乘以机器数反推总容量
架构图
![](https://i-blog.csdnimg.cn/blog_migrate/6384b7d98c1e21dc10d87bed65703879.jpeg)
用 Spring 配置声明暴露服务
- provider.xml
- consumer.xml
Dubbo常用策略
启动时检查
Dubbo 缺省会在启动时检查依赖的服务是否可用,不可用时会抛出异常,阻止 Spring 初始化完成,以便上线时,能及早发现问题,默认 check=“true”。
可以通过 check=“false” 关闭检查,比如,测试时,有些服务不关心,或者出现了循环依赖,必须有一方先启动。
<dubbo:reference interface="com.foo.BarService" check="false" /> <!— 关闭某个服务的启动时检查 (没有提供者时报错) —>
<dubbo:consumer check="false" /> <!— 关闭所有服务的启动时检查 (没有提供者时报错) —>
<dubbo:registry check="false" /> <!— 关闭注册中心启动时检查 (注册订阅失败时报错) —>
集群容错
在集群调用失败时,Dubbo 提供了多种容错方案,缺省为 failover 重试,分别如下:
- failsafe 失败安全,可以认为是把错误吞掉(记录日志)
- failover(默认) 重试其他服务器; retries(2)
- failfast 快速失败, 失败以后立马报错
- failback 失败自动恢复。 后台记录失败请求,定时重发
- forking 并行调用多个服务器,只要一个成功就返回。 只能应用在读请求
- broadcast 广播调用所有提供者,逐个调用。其中一台报错就会返回异常
通过cluster方式,配置指定的容错方案:
<dubbo:service interface=“com.alibaba.hello.api.HelloService” cluster="failsafe" />
<!-- 或者 -->
<dubbo:reference interface=“com.alibaba.hello.api.HelloService” cluster="failsafe" />
负载均衡策略
Dubbo 提供了多种均衡策略,缺省为 random 随机调用。
-
Random LoadBalance
随机,按权重设置随机概率
在一个截面上碰撞的概率高,但调用量越大分布越均匀,而且按概率使用权重后也比较均匀,有利于动态调整提供者权重 -
RoundRobin LoadBalance
轮循,按公约后的权重设置轮循比率
存在慢的提供者累积请求的问题,比如:第二台机器很慢,但没挂,当请求调到第二台时就卡在那,久而久之,所有请求都卡在调到第二台上。 -
LeastActive LoadBalance
最少活跃调用数,相同活跃数的随机,活跃数指调用前后计数差
使慢的提供者收到更少请求,因为越慢的提供者的调用前后计数差会越大 -
ConsistentHash LoadBalance
一致性 Hash,相同参数的请求总是发到同一提供者
当某一台提供者挂时,原本发往该提供者的请求,基于虚拟节点,平摊到其它提供者,不会引起剧烈变动
缺省只对第一个参数 Hash,如果要修改,请配置 <dubbo:parameter key=“hash.arguments” value=“0,1” />
缺省用 160 份虚拟节点,如果要修改,请配置 <dubbo:parameter key=“hash.nodes” value=“320” />
spring配置方法:
<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>
多协议
Dubbo 允许配置多协议,在不同服务上支持不同协议或者同一服务上同时支持多种协议
<!-- 多协议配置 -->
<dubbo:protocol name="dubbo" port="20880" />
<dubbo:protocol name="rmi" port="1099" />
<dubbo:service interface="com.alibaba.hello.api.HelloService" version="1.0.0" ref="helloService" protocol="dubbo" /> <!-- 使用dubbo协议暴露服务 -->
<dubbo:service interface="com.alibaba.hello.api.DemoService" version="1.0.0" ref="demoService" protocol="rmi" /> <!-- 使用rmi协议暴露服务 —>
![](https://i-blog.csdnimg.cn/blog_migrate/521f9fddf12f03f7d5a5ad4851b3bdaa.jpeg)
![](https://i-blog.csdnimg.cn/blog_migrate/e6cf2f4a26c1e5420c6429dceea0dff0.jpeg)
![](https://i-blog.csdnimg.cn/blog_migrate/0a0cff54b654b8bf3bd3600ea7b5366a.jpeg)
多注册中心支持
![](https://i-blog.csdnimg.cn/blog_migrate/de50b3066392d188fae2bd37ceed692c.jpeg)
多版本支持
-
服务端
-
客户端
异步调用
注意hessian协议不支持异步调用,使用async异步回调会报错,但是dubbo协议支持。
异步调用原理如下图:
spring配置如下(这里配置在消费端方法上,也可以配置在消费端服务上):
代码逻辑如下:
dubbo服务只订阅不注册(常用于多注册中心)
去zk上拉取服务列表但不发布自己的服务到zk
dubbo服务只注册不订阅(常用于多注册中心)
只会将服务发布到zk但不会拉取服务列表
设置服务的超时时间(单位: 毫秒)
![](https://i-blog.csdnimg.cn/blog_migrate/8138d2ebba3516042b731b14c740dee4.jpeg)
建议由服务提供方设置超时,因为一个方法需要执行多长时间,服务提供方更清楚
配置dubbo缓存文件(缓存"注册中心的列表”和”服务提供者列表”防止ZK挂掉或网络异常)
![](https://i-blog.csdnimg.cn/blog_migrate/9d76f8d3bb70242595f567346450bfa5.jpeg)
配置优先级别
spring配置在整个集群中的优先级
- 方法级优先,接口级次之,全局配置再次之(就是如果方法中配置了(如”timeout"),接口上的配置会被方法的配置覆盖掉)
- 如果级别一样,则消费方优先,提供方次之