Dubbo_扩展

系列文章目录

提示:这里可以添加系列文章的所有文章的目录,目录需要自己手动添加
Dubbo_扩展


提示:写完文章后,目录可以自动生成,如何生成可参考右边的帮助文档

文章目录

  • 系列文章目录
  • 前言
  • 一、Dubbo高级特性
    • 地址缓存
    • 超时机制
      • 服务生产端设置超时机制
      • 服务消费端设置超时机制
    • 重试机制
    • 灰度发布
      • 老版本服务提供者配置
      • 新版本服务提供者配置
      • 新版本服务消费者配置
      • 不需要区分版本配置
    • 负载均衡
      • 生产者服务
      • 消费者服务
    • 集群容错
      • 集群容错和重试机制的区别
    • 服务降级
    • 服务限流
    • 限流算法
      • 漏桶 vs 令牌桶的区别
      • 服务限流的实现
        • 并发控制
        • 连接控制
      • 服务降级和服务限流的区别
    • 结果缓存
  • 总结


前言

提示:这里可以添加本文要记录的大概内容:

在分布式系统和微服务架构中,Dubbo 是一个非常流行和强大的开源框架。它提供了一系列高级特性,使开发人员能够构建高可扩展、高可用的分布式应用程序。
本博客将深入探讨 Dubbo 的一些高级特性,帮助你更好地理解和利用这些特性来解决实际的业务问题。我们将介绍如服务动态路由、服务治理、负载均衡策略、容错机制等方面的内容。
通过深入了解 Dubbo 的高级特性,你将能够更好地应对分布式系统中的复杂性,提高应用程序的可靠性、可扩展性和性能。无论你是刚刚开始使用 Dubbo,还是已经有一定经验的用户,本博客都将为你提供有价值的信息和实用的技巧。
让我们一起探索 Dubbo 的高级特性,提升你的分布式应用开发技能,构建更加强大和可靠的系统!


提示:以下是本篇文章正文内容,下面案例可供参考

一、Dubbo高级特性

地址缓存

Dubbo 的地址缓存是指 Dubbo 在初始化时会将注册中心的地址缓存下来,避免频繁访问注册中心导致性能下降。当注册中心的地址发生变化时,Dubbo 会重新从注册中心获取地址并更新缓存。
地址缓存有以下几个优点:

  • 提高性能:通过缓存注册中心的地址,减少了对注册中心的访问次数,从而提高了系统的性能。
  • 提高可靠性:当注册中心不可用时, Dubbo 仍然可以通过本地缓存来获取服务提供者的地址,从而保证了系统的可靠性。
  • 实现动态路由: Dubbo 可以通过地址缓存来实现动态路由,根据服务的负载情况将请求动态地路由到不同的服务提供者上,从而提高了系统的可扩展性。

需要注意的是,地址缓存的时间不宜过长,否则可能会导致缓存中的地址过时。通常情况下, Dubbo 会在一定时间后自动更新地址缓存,以保证缓存中的地址是最新的。

超时机制

当服务消费者在调用服务提供者时出现阻塞或等待的情况,服务消费者会一直等待下去,直到服务提供者响应或超时。在某个访问的峰值时刻,大量的请求都在同时访问服务消费者,会造成大量线程堆积,从而导致服务器雪崩。为了解决这个问题,Dubbo可以利用超时机制来设置一个超时时间,在这个时间段内,无法完成服务访问,则会自动断开连接。
在Dubbo中,超时机制可以在服务提供方的@service注解中通过timeout属性设置,也可以在服务消费方的@Reference注解中通过timeout属性设置。并且,服务消费方设置的超时时间优先级高于服务提供方设置的超时时间
需要注意的是,一般不建议在服务消费方设置超时时长,因为一般消费方调用提供者的方法,提供方一般对自己程序的操作时长(查询数据库等)会有大概的估算,会给出超时时长的设置,服务消费方一般不用设置。

服务生产端设置超时机制

使用timeout属性配置超时时间,默认值1000,单位毫秒。

@Service(timeout = 3000) //当前服务3秒超时
public class OrderServiceImpl implements IOrderService {

服务消费端设置超时机制

@Reference(timeout = 2000)// 远程注入
private IOrderService iOrderService;

重试机制

当 Dubbo 服务在尝试调用一次之后,如出现非业务异常(服务突然不可用、超时等),Dubbo 默认会进行额外的最多2次重试。

@Service(timeout = 3000,retries = 2)

灰度发布

灰度发布是指在集群部署的服务中,先发布其中一部分服务,使得集群服务中一部分是老版本服务逻辑,一部分是新版本服务逻辑,这种中间状态的发布状态叫做灰度发布。
以一个User系统为例,有一个查询用户英文名的功能,该功能返回用户的英文名的全名(firstName+lastName),User系统在生产环境中被部署到5台服务器组成的集群上。现在需要修改该功能,使得该功能只需要返回用户英文名的firstName,功能修改完后,经过了完整的测试后,需要将该功能进行生产发布。如果将该新功能直接同时部署到5台服务器组成的集群上,那么如果该功能仍然有缺陷,那么将影响所有用户,所以为了稳当,将该功能先部署到其中两台服务器上,这是集群中3台服务器是旧版本,2台服务器是新版本,并且还需要控制用户的流量,使得生产测试用户使用的是新版本(2台服务器),其他大部分用户使用的仍然是旧版本(另外3台服务器)。当生产测试用户测试过新版本后,如果新版本没有问题,则将另外3台也部署成新版本,移除流量控制,使得所有用户随机访问5台服务器。

老版本服务提供者配置

@Service(version = "1.0.0")
public class OrderServiceImpl implements IOrderService {


public CommonResult findByUserId(Long id) {
    CommonResult<Orders> commonResult = new CommonResult();
    // 返回结果编码
    commonResult.setCode(200);
    // 返回结果描述
    commonResult.setMessage("success");
    // TODO 模拟数据库操作
    // 数据
    Orders orders = new Orders();
    orders.setId(1L);
    orders.setUserId(2L);
    orders.setPrict(12.5);
    orders.setMobile("1888888888");
    orders.setAddress("北京");
    orders.setPay_method(1);
    commonResult.setData(orders);
    return commonResult;
   }
}

新版本服务提供者配置

@Service(version = "2.0.0")
public class OrderServiceImpl implements IOrderService {
public CommonResult findByUserId(Long id) {
    CommonResult<Orders> commonResult = new CommonResult();
    // 返回结果编码
    commonResult.setCode(200);
    // 返回结果描述
    commonResult.setMessage("success");
    // TODO 模拟数据库操作
    // 数据
    Orders orders = new Orders();
    orders.setId(1L);
    orders.setUserId(2L);
    orders.setPrict(12.5);
    orders.setMobile("1888888888");
    orders.setAddress("北京");
    orders.setPay_method(1);
    commonResult.setData(orders);
    return commonResult;
   }
}

新版本服务消费者配置

@Reference(version = "2.0.0")
private IOrderService iOrderService;// 订单服务

不需要区分版本配置

@Reference(version = "*")
private IOrderService iOrderService;// 订单服务

负载均衡

在分布式系统中,为了提高系统的可靠性和性能,通常会将服务部署在多个节点上,形成一个服务集群。当有多个服务实例可用时,需要一种机制来决定将请求发送到哪个服务实例,这就是负载均衡。

Dubbo 提供了多种负载均衡策略,默认使用随机负载均衡,以实现请求在多个服务实例之间的分配。常见的负载均衡策略包括:

  • RandomLoadBalance:随机负载均衡,随机的选择一个,默认负载均衡。
  • RoundRobinLoadBalance:轮询负载均衡。
  • LeastActiveLoadBalance:最少活跃调用数,相同活跃数的随机。
  • ConsistentHashLoadBalance:一致性哈希负载均衡,相同参数的请求总是落在同一台机器上。

生产者服务

@Service(timeout = 3000,retries = 3,loadbalance = "roundrobin")

消费者服务

@Reference(timeout = 2000,loadbalance = "roundrobin"

集群容错

Dubbo框架为服务集群容错提供了一系列好的解决方案,在此称为dubbo服务集群容错模式。Dubbo 目前提供了6种集群容错策略。具体介绍如下:

  • failover 失败自动切换策略:当消费者调用提供者集群中的某个服务器失败时,其会自动尝试着调用其它服务器。该策略通常用于读操作,例如,消费者要通过提供者从数据库中读取某些数据。但重试会带来服务延迟。重试次数可通过 retries 属性指定,缺省为2次。注意,设置的重试次数不包括调用失败的第1次。
  • failfast 快速失败策略:消费者端只发起一次调用,若失败则立即报错。通常用于非幂等性的写操作,比如新增一条记录。
  • failsafe 失败安全策略:当调用过程中出现异常时,Dubbo 仅会打印异常,而不会抛出异常。而当消费者调用提供者出现异常时,直接忽略本次调用。该策略通常用于执行相对不太重要的服务,例如,写入审计日志等操作。
  • failsafe 失败安全策略:当调用过程中出现异常时,Dubbo 仅会打印异常,而不会抛出异常。而当消费者调用提供者出现异常时,直接忽略本次调用。该策略通常用于执行相对不太重要的服务,例如,写入审计日志等操作。
  • forking 并行调用策略,即并行调用多个服务提供者。消费者对于同一服务并行调用多个提供者服务器,只要一个成功即调用结束并返回结果。通常用于实时性要求较高的读操作,但其会浪费较多服务器资源。可以通过设置 forks 属性来指定可以并行调用的服务提供者数量。
  • broadcast 广播策略:广播调用所有提供者,逐个调用,任意一台报错则报错。通常用于通知所有提供者更新缓存或日志等本地资源信息。

注意:配置集群容错策略时,容错策略可以设置在消费者端,也可以设置在提供者端,最小粒度可以设置到方法级别。若消费者与提供者均做了设置,则消费者端的优先级更高。

集群容错和重试机制的区别

  • 集群容错是一种用于处理服务调用失败的机制,当服务提供者集群中的某个节点出现故障或无法响应时,集群容错机制可以自动将请求路由到其他可用的节点,以保证服务的可用性和可靠性。
  • 重试机制是指当服务调用失败时,自动进行多次重试,以提高服务的成功率和可靠性。重试机制适用于一些暂时性的故障或网络抖动等情况。

服务降级

服务降级是指在系统高负载或某些服务出现故障时,为了保证系统的整体可用性,将一些非核心服务或功能暂时降低其优先级或暂停使用的策略。服务降级的两种场景:

  • 当下游的服务因为某种原因响应过慢,下游服务主动停掉一些不太重要的业务,释放出服务器资源,增加响应速度!
  • 当下游的服务因为某种原因不可用,上游主动调用本地的一些降级逻辑,避免卡顿,迅速返回给用户!

服务降级的两种方式:

  • mock=force:return null,表示消费方对该服务的方法调用都直接返回null值,不发起远程调用。用来屏蔽不重要服务不可用时对调用方的影响。

  • mock=force:return null,表示消费方对该服务的方法调用在失败后,再返回null值,不抛异常。用来容忍不重要服务不稳定时对调用方的影响。

###服务降级演示

@Reference(timeout = 2000,mock = "force:return null")
private IOrderService iOrderService;

服务限流

服务限流是指当系统资源不够,不足以应对大量请求,即系统资源与访问量出现矛盾的时候,为了保证有限的资源能够正常服务,对系统按照预设的规则进行流量限制或功能限制的一种策略。

限流算法

  • 漏桶算法:假设有一个固定容量的桶,流速(系统处理能力)固定,如果一段时间水龙头水流太大,水就溢出了(请求被抛弃了)。该算法每次请求进来都放入一个先进先出的队列中,队列满了,则直接返回失败。另外有一个线程池固定间隔不断地从这个队列中拉取请求。
  • 令牌桶算法:有一个固定容量的桶,桶里存放着令牌(token)。桶一开始是空的,令牌以一个固定的速率往桶里填充,直到达到桶的容量,多余的令牌将会被丢弃。每当一个请求过来时,就会尝试从桶里移除一个令牌,如果没有令牌的话,请求无法通过。

漏桶 vs 令牌桶的区别

漏桶的天然特性决定了它不会发生突发流量,就算每秒1000个请求到来,那么它对后台服务输出的访问速率永远恒定。而令牌桶则不同,其特性可以“预存”一定量的令牌,因此在应对突发流量的时候可以在短时间消耗所有令牌,其突发流量处理效率会比漏桶高,但是导向后台系统的压力也会相应增多。

服务限流的实现

并发控制

服务端并发执行(或占用线程池线程数)不能超过10个

@Service(executes = 10)
连接控制

占用连接的请求的数不能超过10个。

@Service(actives= 10)

服务降级和服务限流的区别

  • 服务降级是指在系统高负载或某些服务出现故障时,为了保证系统的整体可用性,将一些非核心服务或功能暂时降低其优先级或暂停使用的策略。
  • 服务限流是指对系统的请求进行限制,以防止过多的请求同时涌入系统,导致系统资源耗尽或性能下降的策略。

结果缓存

结果缓存用于加速热门数据的访问速度, Dubbo 提供声明式缓存,以减少用户加缓存的工作量。 Dubbo 缓存是在本地缓存,在分布式服务中,会缓存多份,在每个服务中缓存。其配置操作简单,只需设置dubbo:reference或dubbo:method的cache属性,指定需要使用的缓存类型即可。Dubbo 提供了三种结果缓存机制:

  • LRU(Least Recently Used):基于最近最少使用原则删除多余缓存,保持最热的数据被缓存。
  • ThreadLocal:当前线程缓存。比如渲染一个页面,用到很多portal,每个portal都要去查用户信息,通过线程缓存,可以减少这种多余缓存。
  • JCache:可以桥接各种缓存实现。
@reference(cache="lru")

总结

提示:这里对文章进行总结:

以上是 Dubbo 高级特性的一些关键要点。这些特性有助于提高系统的稳定性、性能和可扩展性,使其能够更好地应对高并发和复杂的业务需求。

你可能感兴趣的:(Dubbo,dubbo,Dubbo,容错机制,服务降级)