负载均衡
Dubbo 里面默认就集成了负载均衡的算法和实现,默认提供了 4 中负载均衡实现:
- 权重随机:roundrobin
- 最小活跃度:leastactive
- 权重轮询:roundrobin
- 一致性hash:leastactive
Dubbo中负载均衡的应用方式:
1.配置文件
<dubbo:reference interface="..." loadbalance="roundrobin" />
2.注解
@Reference(loadbalance = "random")
LoginService loginService;
算法思路
RandomLoadBalance
假设有一组服务[A,B,C],他们对应的权重为 weights=[5,3,2],权重总和为10。接下来通过 随机数生成器生成一个范围在 [0,10) 之间的随机数,然后计算这个随机数会落到哪个 区间上。比如数字 3 会落到服务器 A 对应的区间上,此时返回服务器 A 即可。
LeastActiveLoadBalance
最少活跃调用数算法,活跃调用数越小,表明该服务提供者效率越高,单位时间内可处理更多的请求这个是比较科学的负载均衡算法。
每个服务提供者对应一个活跃数 active。初始情况下,所有服务提供者活跃数均为 0。 每收到一个请求,活跃数加 1,完成请求后则将活跃数减 1。在服务运行一段时间后, 性能好的服务提供者处理请求的速度更快,因此活跃数下降的也越快,此时这样的服 务提供者能够优先获取到新的服务请求。
ConsistentHashLoadBalance
hash 一致性算法,相同参数的请求总是发到同一提供者。
RoundRobinLoadBalance
我们对轮询过程进行加权,以调控每台服务器的负载。经过加权后,每台服务器能够得到的请求数比例,接近或等于他们的权重比。
容错机制
<dubbo:reference interface="..." cluster ="" />
集群方式,可选:
failover:失败自动切换,当出现失败,重试其它服务器。(缺省)
failfast:快速失败,只发起一次调用,失败立即报错。
failsafe:失败安全,出现异常时,直接忽略。
failback:失败自动恢复,后台记录失败请求,定时重发。
forking:并行调用多个服务器,只要一个成功即返回。可通过 forks="2" 来设置最大并行数。
<dubbo:reference interface="..." retries =""/>
远程服务调用重试次数,不包括第一次调用,不需要重试请设为0
服务降级
当某个非关键服务出现错误时,可以通过降级功能来临时屏蔽这个服务。降级可以有几个层面的分类: 自动降级和人工降级; 按照功能可以分为:读服务降级和写服务降级:
- 对一些非核心服务进行人工降级,在大促之前通过降级开关关闭哪些推荐内容、评价等对主流程没有影响的功能。
- 故障降级,比如调用的远程服务挂了,网络故障、或者 RPC 服务返回异常。 那么 可以直接降级,降级的方案比如设置默认值、采用兜底数据(系统推荐的行为广告挂了,可以提前准备静态页面做返回)等等。
- 限流降级,在秒杀这种流量比较集中并且流量特别大的情况下,因为突发访问量特别大可能会导致系统支撑不了。这个时候可以采用限流来限制访问量。当达到阀值 时,后续的请求被降级,比如进入排队页面,比如跳转到错误页(活动太火爆,稍后重试等)。
Dubbo 实现服务降级
在客户端实现一个Mock类,当出现服务降级时,会被调用
public class MockSayHelloService implements HelloService {
@Override
public String sayHello() {
return "Sorry, 服务端发生异常,被降级啦!";
}
}
修改客户端的注解,增加 mock 配置,以及修改 timeout=1, 表示本次调用的超时时 间是 1 毫秒,这样可以模拟出失败的场景。
需要配置 cluster=failfast,否则因为默认是 failover 导致客户端会发起 3 次重试,等待的时间比较长
<dubbo:reference interface="com.springboot.test.dubboClient.MockSayHelloService" check="false" id="userApiService" timeout="1" registry="zkreg" version="1.0.0" mock="com.springboot.test.dubboConsumer.MockSayHelloService" loadbalance = "random" cluster = "failfast" />