专栏首页中间件兴趣圈Sentinel Dubbo 适配器看限流与熔断(实战思考篇)

Sentinel Dubbo 适配器看限流与熔断(实战思考篇)

本文是源码分析 Sentinel 系列的第十三篇,已经非常详细的介绍了 Sentinel 的架构体系、滑动窗口、调用链上下文、限流、熔断的实现原理,相信各位读者朋友们对Sentinel有一个较为体系化的认知了,这个时候是该开始如何在生产环境进行运用了。

本文将以 Dubbo 服务调用为案例剖析场景,尝试对官方提供的 Dubbo 适配器做一个研究学习并对此做出自己的评价,抛出我的观点,期待与大家共同探讨,交流。

一个 Dubbo RPC 的简易调用过程如下图所示:

消费者会维护一个服务提供者列表,然后再发一起一个服务调用的时候会首先根据负载均衡算法从中选择一个服务提供者,然后发起 RPC 调用,在请求真实发送之前会依次通过客户端设置的过滤器链(Filter),然后经过网络传输到到达服务提供者,并执行完服务提供者端的 Filter,最后进入到业务逻辑执行并返回结果。

Sentinel 与 Dubbo 的整合就是利用了 Dubbo 的 Filter 机制,为 Dubbo 提供对应的 过滤器,无缝实现限流、熔断等功能,做到业务无感知,即业务代码无需使用 Sentinel 相关的 API。

接下来请大家带着在 Dubbo 中如何使用限流、熔断方面来看官方给出的解决方案。

思考题:在看接下来的内容之前,建议大家稍作停顿,思考一下,在服务调用模型中,限流、熔断通常在哪个端做比较合适。

1、从消费端来看限流与熔断


从消费端的视角,虽然提供了服务端的负载均衡,但从客户端不管是向192.168.1.3还是向192.168.1.4发送RPC调用,都会经过同一个 Sentinel Dubbo Filter。这个看似简单明了,但这是我们接下来思考的最基本最核心的点。

我们先来看看官方提供的 Dubbo 适配器的核心实现:

SentinelDubboConsumerFilter#invoke消费端这边使用到了两个资源名称,一个是接口级别,例如 com.demo.service.UserService,另外一是方法级别,例如 com.demo.servcie.UserServce#findUser(Ljava.lang.String)。

定义了两个资源后,Sentinel 会使用滑动窗口机制,为上述两个资源收集实时的调用信息,为后续的限流、熔断提供数据依据。

限流规则是依附于具体某一个项目的,例如如下图所示:

限流、熔断都是根据资源级别,如果需要对消费端的调用进行限流的话,就需要为这两个资源配置对应的限流规则,如果不配置则默认通过,表示不限流。

1.1 服务调用端(消费方)是否需要配置限流规则

在 dubbo 的服务调用场景中,在消费端设置限流的规则的话,这个调用链是针对整个集群所有服务提供者的,例如当前集群中包含3个服务提供者,每个服务提供者用于1000tps的服务能力,那消费端的限流,应该配置的限流TPS应该为3000tps,如果设置为1000tps,则无法完整的利用服务端的能力,基于这样的情况,通常消费端无需配置限流规则。

那是不是说消费端就没必要配置限流规则呢?其实也不是,有如下这个场景,例如调用第三方外部的计费类服务接口,对方通常为特定的账户等级设置对应的TPS上限,如果超过该调用频率就会抛出错误,这种情况还是需要设置限流规则,确保消费端以不超过要求进行调用,避免业务异常。

1.2 服务调用端(消费方)是否需要配置熔断

引入熔断的目的是避免服务端单节点响应慢而导致这个服务不稳定,例如示例中有3个服务提供者,如果192.168.1.3的服务提供者由于触发了BUG导致响应时间大大增加,导致发往该服务提供者的请求大概率超时,在这样的情况下希望在接下来某段时间内消费方发往这这个服务提供者的请求快速熔断降级,返回错误,由客户端重试其他服务提供者。其实现效果如下:

当前的 Sentinel 默认是否能满足上述的需求呢?

我们以 Sentinel 基于异常比例熔断策略来进行阐述,如果资源的调用异常比例超过一定值是会触发降级熔断,抛出 DegradeException 异常。

由于总共只有三个服务提供者,其中发往192.168.1.3的请求大概率会由于超时失败,则异常比例会超过设置的熔断降级规则,会触发降级,造成的效果是整个服务调用都会发送熔断降级,即调用192.168.1.4,5两个请求都不会被熔断,造成整个服务调用不可用,与期望不一致。即还是会出现一个节点的不稳定而导致整个服务不稳定的情况。

其造成的根本原因是因为其资源的定义并没有包含服务提供者的信息,改进的初步方案:

  1. 在过滤器中再定义一个资源,加上服务提供的IP与端口号,例如 SphU.entry("com.d.s.UserService@ip:port"),对单个服务提供者进行单独收集调用信息,并且需要提供一可配置的项,用来标记该类型的资源在做熔断判断可使用某一个资源的配置,例如配置为 com.d.s.UserService,表示用这个配置规则来判断熔断。
  2. 在熔断规则判断的时候,该资源使用被引用资源的熔断规则进行判断。

最后来解答一下,熔断规则通常只需要配置在调用方即可。

2、从服务端来看限流与熔断


由于服务端看限流与熔断就比较简单,因为服务端与客户端存在一个非常大的区别是客户端存在负载均衡机制,一个消费端对于同一资源来说,会调用多个服务提供者,而服务提供者对于一个资源来就是其自身,故限流规则,熔断规则都是针对个体,其复杂度降低。

为了知识体系的完备性,我们来看一下 Sentinel Dubbo 在服务端的适配器的实现。

SentinelDubboProviderFilter#invoke 这里有二个关键点:

  1. 使用了 ContextUtil 的 entry 方法,定义本次调用的上下文环境名称为:resourceName,默认为接口名与方法名、参数列表,例如 com.d.s.UserServce#findUser(Ljava.lang.String),源头为消费端的应用名称。
  2. 定义两个资源,这里与消费端相同,就不做重复解读。

关于这个 ContextUtil 的 entry 方法非常关键,因为 Sentinel 中数据节点的统计是以 ContextName 为维度的。

例如想对一个应用所有的操作 redis 操作统一设置为一个资源名,redisOpsResource,即想控制该应用整体的 redis 操作 tps,其场景如下:

例如初衷设计为 opsReisTotal 的整个 tps 为 500,例如从UserService#findser链路的访问 redis tps 为 400,而从 Order#createOrder 链路访问 redis tps 为 400,此时 redis 的整体 tps 已经达到了 800 tps,但你会发现并不会触发限流,因为对资源 RredisOpResource 的调用信息统计是以 context name 为维度的,不同的 context name 互不影响,从而无法做到全局控制。

3、总结


本文结合 Sentinel 官方对于 Dubbo 提供的适配器并加以理解,提出了如下观点,欢迎大家留言探讨,相互交流,共同进步。

  1. 限流规则根据不同的使用场景可以在客户端、服务端配置。
  2. 熔断规则通常在服务调用方配置即可。
  3. Sentinel 目前的熔断还实现的比较简单,无法解决集群中因为某一个节点的访问慢而触发熔断,并使服务稳定的能力。
  4. Sentienl 的实时统计是以调用上下文(Context Name),即 ContextUtil.entry 方法定义的上下文为维度的,这点非常关键,不然容易踩坑。

本文分享自微信公众号 - 中间件兴趣圈(dingwpmz_zjj),作者:丁威

原文出处及转载信息见文内详细说明,如有侵权,请联系 yunjia_community@tencent.com 删除。

原始发表时间:2020-05-11

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

我来说两句

0 条评论
登录 后参与评论

相关文章

  • 结合 Sentinel 专栏谈谈我的源码阅读方法

    Sentinel 系列共包含15篇文章,主要以源码分析为手段,图文并茂的方式对 Sentinel 的架构设计理念、核心实现要点进行了一一剖析,并加以实战分析与思...

    丁威
  • 源码分析 Sentinel 之 Dubbo 适配原理

    在Alibaba Sentinel 限流与熔断初探(技巧篇) 的示例中我选择了 sentinel-demo-apache-dubbo 作为突破点,故本文就从该项...

    丁威
  • 没有 “流量防控”,还玩什么双11

    临近双十一,从 2009 年第一届双十一开始,成交量只有 5000 万,到去年 2019 年,成交量达到了 2684 亿。今年迎来了第十二届双十一,想想都挺激动...

    xjjdog
  • 流量防控该如何选型?

    临近双十一,从 2009 年第一届双十一开始,成交量只有 5000 万,到去年 2019 年,成交量达到了 2684 亿。今年迎来了第十二届双十一,想想都挺激动...

    悟空聊架构
  • Sentinel源码分析,了解Sentinel的整个工作流程

    从上一篇《Sentinel限流的核心功能QPS统计的实现原理》我们了解到,Sentinel统计QPS使用的是时间窗口+Bucket,并且通过循环复用Bucket...

    Java艺术
  • hystrix与sentinel的区别以及选型对比

    开发架构二三事
  • 轻松两步,在 SpringBoot 服务上实现接口限流

    在日常开发中,限流功能时常被使用,用于对某些接口进行限流熔断,譬如限制单位时间内接口访问次数;或者按照某种规则进行限流,如限制ip的单位时间访问次数等。

    java进阶架构师
  • 优秀工程师必备技能之如何高效阅读源码

    “平时不用看源码, 看源码太费时间,还容易忘记,工作中出现问题再针对性地阅读,效率更高。”

    码哥字节
  • 一文带你通过Sentinel源码,读懂微服务限流底层原理!

    限流是保障服务高可用的方式之一,尤其是在微服务架构中,对接口或资源进行限流可以有效地保障服务的可用性和稳定性。

    Java程序猿
  • Sentinel 调用上下文环境实现原理(含原理图)

    我们从 sentinel-apache-dubbo-adapter 模块的 SentinelDubboProviderFilter 的实现中不难看出,在其入口...

    丁威
  • Sentinel 流量控制 熔断降级 初探 原

        还记得之前写过一篇防雪崩利器:熔断器 Hystrix 的原理与使用https://my.oschina.net/u/3266761/blog/26544...

    chinotan
  • 啥 啥 啥,服务治理是个啥

    首先,先说下服务治理的边界,本质上任何能提升服务可用性,性能,让服务更稳定等等,只要是能让服务运行的更好,都属于服务治理的范畴。服务治理比较常见的话题:服务发现...

    luoxn28
  • Sentinel: 分布式系统的流量防卫兵

    随着微服务的流行,服务和服务之间的稳定性变得越来越重要。Sentinel 以流量为切入点,从流量控制、熔断降级、系统负载保护等多个维度保护服务的稳定性。

    35岁程序员那些事
  • 《一起学sentinel》一、一起搭建sentinel服务

    随着微服务的流行,服务和服务之间的稳定性变得越来越重要。Sentinel 以流量为切入点,从流量控制、熔断降级、系统负载保护等多个维度保护服务的稳定性。

    M4Y
  • OpenFeign整合Sentinel实现熔断降级

    常用于实现熔断降级的框架有Hystrix、Sentinel,我们常说的Spring Cloud项目说的其实是Spring Cloud Netflix,Hystr...

    Java艺术
  • 限流神器Sentinel,不了解一下吗?

    书接上回: 你来说说什么是限流? ,限流的整体概述中,描述了 限流是什么,限流方式和限流的实现。在文章尾部的 分布式限流,没有做过多的介绍,选择了放到这篇文章中...

    九灵
  • 基于 Sentinel 作熔断

    我们都知道Spring cloud 作熔断降级的组件 Hystrix,Spring cloud 之熔断机制(实战)一文中,也讲述了如何使用 Hystrix,这是...

    程序猿Damon
  • Spring Cloud Alibaba 系列之 Sentinel 介绍

      随着微服务的流行,服务和服务之间的稳定性变得越来越重要。Sentinel 以流量为切入点,从流量控制、熔断降级、系统负载保护等多个维度保护服务的稳定性。Se...

    Demo_Null
  • Hystrix停止更新了!告诉你如何应对!

    随着微服务的流行,服务和服务之间的稳定性变得越来越重要。流量控制、熔断降级、系统负载保护等技术被广泛使用于微服务体系,用以提升系统的健壮性和保障业务的稳定性,避...

    lyb-geek

扫码关注云+社区

领取腾讯云代金券