dubbo学习笔记(二)——dubbo的服务治理功能

一、负载均衡

1、背景

dubbo集成zookeeper解决了服务注册以及服务动态感知的问题。当服务端存在多个节点的集群时,zookeeper 上会维护不同集群节点。这时候就需要一种负载均衡机制来实现目标服务的请求负载。通过负载均衡,可以让每个服务器节点获得适合自己处理能力的负载。

负载均衡可以分为软件负载和硬件负载,在实际开发中,我们基础软件负载比较多,比如 nginx,硬件负载现在用得比较少而且有专门的人来维护。Dubbo 里面默认就集成了负载均衡的算法和实现,默认提供了 4 中负载均衡实现

2、dubbo实现负载均衡

dubbo配置负载均衡有两种方式:基于xml配置文件;基于注解。配置loadbalance属性。
loadbalance可以配置四种:roundrobin/random/leastactive/ consistenthash。
xml配置:

<!--服务端配置-->
<dubbo:service interface="..." loadbalance="roundrobin" />
<!--客户端配置-->
<dubbo:reference interface="..." loadbalance="roundrobin" />

注解配置:

//服务端
@Service(loadbalance = "roundrobin")
public class HelloServiceImpl implements HelloService{
	...
}
//客户端使用属性注入的方式
public class HelloController{
	@Reference(loadbalance = "random")
	public IHelloService helloService;
}

dubbo配置负载均衡可以在客户端配置,也可以在服务端配置。但是最后以客户端为准。而且dubbo的负载均衡机制是在客户端生效。dubbo的负载均衡算法如下:
权重随机算法(RandomLoadBalance)
对应的配置为loadbalance = “random”。根据权重值进行随机负载。它的算法思想很简单。假设我们有一组服务器 servers = [A, B, C],他们对应的权重为weights = [5, 3, 2],权重总和为 10。现在把这些权重值平铺在一维坐标值上,[0, 5) 区间属于服务器 A,[5, 8) 区间属于服务器 B,[8, 10) 区间属于服务器 C。接下来通过随机数生成器生成一个范围在 [0, 10) 之间的随机数,然后计算这个随机数会落到哪个区间上。比如数字 3 会落到服务器 A 对应的区间上,此时返回服务器 A 即可。权重越大的机器,在坐标轴上对应的区间范围就越大,因此随机数生成器生成的数字就会有更大的概率落到此区间内。只要随机数生成器产生的随机数分布性很好,在经过多次选择后,每个服务器被选中的次数比例接近其权重比例。

最少活跃调用数算法(LeastActiveLoadBalance)
对应的配置为loadbalance = “leastactive”。最少活跃调用数算法,活跃调用数越小,表明该服务提供者效率越高,单位时间内可处理更多的请求这个是比较科学的负载均衡算法。每个服务提供者对应一个活跃数 active。初始情况下,所有服务提供者活跃数均为 0。每收到一个请求,活跃数加 1,完成请求后则将活跃数减 1。在服务运行一段时间后,性能好的服务提供者处理请求的速度更快,因此活跃数下降的也越快,此时这样的服务提供者能够优先获取到新的服务请求。

hash一致性算法(ConsistentHashLoadBalance)
对应的配置为loadbalance = “consistenthash”。计算请求参数的hash值,hash值相同的请求总是发到同一服务节点,当某个节点宕机后,原本发往该提供者的请求,基于虚拟节点,平摊到其它提供者,不会引起剧烈变动。

加权轮询算法(RoundRobinLoadBalance)
对应的配置为loadbalance = “roundrobin”。所谓轮询是指将请求轮流分配给每台服务器。举个例子,我们有三台服务器 A、B、C。我们将第一个请求分配给服务器 A,第二个请求分配给服务器 B,第三个请求分配给服务器 C,第四个请求再次分配给服务器 A。这个过程就叫做轮询。轮询是一种无状态负载均衡算法,实现简单,适用于每台服务器性能相近的场景下。但现实情况下,我们并不能保证每台服务器性能均相近。如果我们将等量的请求分配给性能较差的服务器,这显然是不合理的。因此,这个时候我们需要对轮询过程进行加权,以调控每台服务器的负载。经过加权后,每台服务器能够得到的请求数比例,接近或等于他们的权重比。比如服务器 A、B、C 权重比为 5:2:1。那么在 8 次请求中,服务器 A 将收到其中的 5 次请求,服务器 B 会收到其中的 2 次请求,服务器 C 则收到其中的 1次请求。

二、容错机制

在分布式网络通信中,容错能力是必须要具备的,容错能力就是容忍错误的能力。在道网络通信会有很多不确定因素,比如网络延迟、网络中断、服务异常等,会造成当前这次请求出现失败。当服务通信出现这个问题时,需要采取一定的措施应对。而 dubbo 中提供了容错机制来优雅处理这种错误。dubbo提供了多种容错机制。

Failover Cluster:
失败自动切换,当出现失败,重试其它服务器。为默认机制。通常用于读操作,但重试会带来更长延迟。可通过 retries=“2” 来设置重试次数(不含第一次)。

//服务端
@Service(cluster = "failover",retries="2" )
//客户端
@Reference(cluster = "failover",retries="2")

//xml配置:
<dubbo:service cluster = "failover" retries="2" />

<dubbo:reference cluster = "failover" retries="2" />

Failfast Cluster:
快速失败,只发起一次调用,失败立即报错。通常用于非幂等性的写操作,比如新增记录。
Failsafe Cluster:
失败安全,出现异常时,直接忽略。通常用于写入审计日志等操作。
Failback Cluster:
失败自动恢复,后台记录失败请求,定时重发。通常用于消息通知操作。
Forking Cluster:
并行调用多个服务器,只要一个成功即返回。通常用于实时性要求较高的读操作,但需要浪费更多服务资源。可通过 forks=“2” 来设置最大并行数。
Broadcast Cluster:
广播调用所有提供者,逐个调用,任意一台报错则报错。通常用于通知所有提供者更新缓存或日志等本地资源信息。可以通过 broadcast.fail.percent 配置节点调用失败的比例,当达到这个比例后,BroadcastClusterInvoker 将不再调用其他节点,直接抛出异常。broadcast.fail.percent 取值在 0~100 范围内。默认情况下当全部调用失败后,才会抛出异常。broadcast.fail.percent 只是控制的当失败后是否继续调用其他节点,并不改变结果(任意一台报错则报错)。broadcast.fail.percent 参数 在 dubbo2.7.10 及以上版本生效。

//broadcast.fail.percent=20 代表了当 20% 的节点调用失败就抛出异常,不再调用其他节点。
@reference(cluster = "broadcast", parameters = {"broadcast.fail.percent", "20"})

Available Cluster:
调用目前可用的实例(只调用一个),如果当前没有可用的实例,则抛出异常。通常用于不需要负载均衡的场景。
Mergeable Cluster:
将集群中的调用结果聚合起来返回结果,通常和group一起配合使用。通过分组对结果进行聚合并返回聚合后的结果,比如菜单服务,用group区分同一接口的多种实现,现在消费方需从每种group中调用一次并返回结果,对结果进行合并之后返回,这样就可以实现聚合菜单项。
ZoneAware Cluster
多注册中心订阅的场景,注册中心集群间的负载均衡。对于多注册中心间的选址策略有如下四种

指定优先级:preferred="true"注册中心的地址将被优先选择

<dubbo:registry address="zookeeper://127.0.0.1:2181" preferred="true" />

同中心优先:检查当前请求所属的区域,优先选择具有相同区域的注册中心

<dubbo:registry address="zookeeper://127.0.0.1:2181" zone="beijing" />

权重轮询:根据每个注册中心的权重分配流量

<dubbo:registry id="beijing" address="zookeeper://127.0.0.1:2181" weight="100" />

<dubbo:registry id="shanghai" address="zookeeper://127.0.0.1:2182" weight="10" />

缺省值:选择一个可用的注册中心

三、服务降级

当某个非关键服务出现错误时,可以通过降级功能来临时屏蔽这个服务。降级可以有几个层面的分类: 自动降级和人工降级; 按照功能可以分为:读服务降级和写服务降级;

  1. 对一些非核心服务进行人工降级,在大促之前通过降级开关关闭哪些推荐内容、评价等对主流程没有影响的功能
  2. 故障降级,比如调用的远程服务挂了,网络故障、或者 RPC 服务返回异常。 那么可以直接降级,降级的方案比如设置默认值、采用兜底数据(系统推荐的行为广告挂了,可以提前准备静态页面做返回)等等
  3. 限流降级,在秒杀这种流量比较集中并且流量特别大的情况下,因为突发访问量特别大可能会导致系统支撑不了。这个时候可以采用限流来限制访问量。当达到阀值时,后续的请求被降级,比如进入排队页面,比如跳转到错误页(活动太火爆,稍后重试等)

Dubbo 中提供了一个 mock 的配置,可以通过mock 来实现当服务提供方出现网络异常或者挂掉以后,客户端不抛出异常,而是通过Mock 数据返回自定义的数据。

在客户端创建一个 mock 类,当出现服务降级时,会被调用。

public class MockSayHelloService implements HelloService {
 @Override
 public String sayHello() {
 return "Sorry, 服务端发生异常,被降级啦!";
 }
}

然后在@Reference中配置mock

public class HelloController{
	//通过属性注入
	@Reference(mock = "包名.MockSayHelloService")
	public HelloService helloService;
	...
}
  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值