为应用配置热点规则后,AHAS将分析统计参数,即资源调用过程中的调用次数较高的参数,并根据配置的热点规则对包含热点参数的资源调用进行限流,保护系统稳定性。本文介绍如何为应用配置热点规则。

背景信息

热点即经常被访问的数据。例如在以下场景中需要统计某个热点数据中访问频次最高的Top数据,并对其访问进行限制。

  • 针对一段时间内最频繁购买的商品ID进行限制,防止击穿缓存而导致大量请求到数据库的情形。
  • 针对一段时间内频繁访问的用户ID进行限制,防止恶意刷单。

AHAS利用LRU(Least Recently Used)策略统计最近最常访问的热点参数,结合令牌桶算法来进行参数级别的流控。

使用说明

将应用接入AHAS应用防护,具体操作请参见接入应用概述

  • 若您通过Dubbo应用方式接入,AHAS应用防护将在方法级别的埋点即方法签名的接口名,自动按次序传入调用的参数,因此可以直接对调用参数配置热点规则。详情请参见接入Dubbo应用
  • 若您通过注解方式接入,Sentinel会将@SentinelResource注解方式定义的资源作为参数传入SphU.entry(res, args)。详情请参见通过注解接入
    例如以下示例中,uidtype会分别作为第一个和第二个参数传入Sentinel API,从而可以用于热点规则判断:
    @SentinelResource(value = "myMethod", blockHandler = "myBlockHandlerFunc")
    public Result doSomething(String uid, int type) {
      // uid参数索引为0,type参数索引为1。
      // some logic here...
    }
  • 对于其它方式接入的应用,您需要自定义埋点传入需要进行热点限流的参数,如IP、User ID等。请参见资源定义类SphU / SphO
    // name: 资源名称,用于标识该调用。
    // EntryType用于区分该资源是入口流量(inbound)还是出口流量(outbound),EntryType.IN代表入口流量,EntryType.OUT代表出口流量。
    // count表示每次调用计数为多少,通常传1。
    // args为传入的参数,用于热点参数限流。
    public static Entry entry(String name, EntryType entryType, int count, Object... args) throws BlockException

    args即待传入的参数,若有多个待传入参数,则按照次序依次传入。例如需要传入两个参数paramA和paramB,传入方式如下:

    // paramA对应的参数索引为0,paramB对应的参数索引为1。
    // 若需要配置例外项或者使用集群维度流控,则传入的参数只支持基本类型。
    SphU.entry(resourceName, EntryType.IN, 1, paramA, paramB);
    若使用SphU.entry()传入了热点参数,那么使用exit的时候也要带上对应的参数(exit(count, args)),否则并发线程数等指标会有统计错误。正确使用如下:
    Entry entry = null;
    try {
        entry = SphU.entry(resourceName, EntryType.IN, 1, paramA, paramB);
        // 用户的业务逻辑。
    } catch (BlockException ex) {
        // 触发限流降级,在此处进行处理。
    } finally {
        if (entry != null) {
            // 务必保证entry成功后最终会exit,并且传入了对应的参数。
            entry.exit(1, paramA, paramB);
        }
    }

功能入口

  1. 登录AHAS控制台
  2. 在AHAS控制台左上角,选择应用接入的地域
  3. 在控制台左侧导航栏中选择流量防护 > 应用防护
  4. 应用列表页面单击目标应用卡片。
  5. 在左侧导航栏单击规则设置,然后单击热点规则页签。
  6. 热点规则页签右上角单击新增热点限流规则
  7. 新增热点限流规则对话框中,配置规则信息。
  8. 单击新增
  9. (可选)若需对某些特殊的热点参数值单独配置阈值,则在规则列表中单击目标规则操作列的添加例外项,然后在热点规则例外项对话框中单击添加,并填写单独配置的参数信息,然后单击确定
    说明 热点规则例外项仅支持基本类型和字符串类型。由于一条规则只对应一个参数索引位置,因此例外项类型需要保持统一。例如在资源R的参数索引0处配置一条热点规则,阈值为5QPS。若在这条规则新增两条例外项:参数Sentinel阈值为100,参数AHAS阈值为200。则实际生效的时候,其它热点参数会限制每秒钟访问不超过5次,而Sentinel和AHAS这两个参数值作为例外项,会按照对应的例外项阈值生效。

常用场景1 秒杀场景

秒杀等抢购商品的时候,由于流量较大会导致系统响应不及时,甚至系统崩溃。为保证系统的稳定性,可配置热点规则,超过一定量的阈值后,系统会让购买热点商品的流量排队等待。

例如购买同一商品,1s内调用超过100次请求后,则其余请求进行等待。在新建热点规则对话框中配置如下规则信息。

  • 填写接口名称
  • 统计维度选择通过请求数
  • 统计周期时间设置为1s,单机阈值设置为100。
  • 流控效果选择排队等待
  • 超时时间设置为30 ms。
新增热点限流规则-ex

1s内调用此接口超过100次,多余的请求要进行排队等待,等待时长超过30 ms的请求就会立即失败。

常用场景2 调用请求频繁,占用较多系统资源

例如秒杀的时候还需要修改下单地址,当调用修改请求较多的时候,会占用了写数据库较多资源,则可以对其进行热点快速失败的处理,稍后再修改。在新建热点规则对话框中配置如下规则信息。

  • 填写接口名称
  • 统计维度选择并发数
  • 统计周期时间设置为1s,单机阈值设置为100。
  • 流控效果选择快速失败
新增热点限流规则-ex2

表示1s内只能最多处理100条修改请求,其余超出的请求都会快速失败。

更多信息

新建热点规则页面参数说明如下。

参数 描述
接口名称 适用该规则的资源名称,与埋点传入的资源名保持一致。
参数位置索引 埋点传入参数的索引位置。对应SphU.entry(xxx,args)中的参数索引位置。例如SphU.entry(resourceName,Entry Type.IN,1,paramA,paramB)埋点中,paramA的参数索引是0,paramB的参数索引是1。
统计维度 可选择通过请求数或并发线程数。
  • 通过请求数:限制一段时间内的调用次数。
  • 并发数:限制该资源调用的并发数。
统计周期时间 统计窗口时间长度(单位为秒)。例如统计窗口时长为10s,QPS阈值为5代表限制10s内每个热点参数访问不超过5次。
单机阈值 是作用于每个热点参数的阈值。
流控效果 统计维度通过请求数时,可以选择流控效果来处理被拦截的流量。
  • 快速失败:达到阈值时,立即拦截请求。该模式下可以额外设置一个缓冲请求数,即针对突发请求额外允许的请求数目。
  • 排队等待:请求匀速通过,允许排队等待,通常用于消息队列削峰填谷等场景。需设置具体的超时时间,排队时会计算预计的排队时长,若超过最大超时时间则请求会直接被拒绝。例如,单机阈值配置为5,则代表请求每200 ms才能通过一个,多出的请求将排队等待通过。超时时间配置1000 ms,则当前排队请求超过5个(>1000 ms)时,新到来的请求将会直接被拒绝。