记一次利用Sentinel提供的aop对接口做热点参数限流

89 阅读2分钟

场景

当前完成了一个商户端接入支付功能的sdk项目,在测试环境上排查问题时需要去捞日志的时候,发现日志基本上被提供给商户查询订单状态的接口日志打满,一来不方便捞日志,二来提醒了我可能需要对查询接口做限流处理,避免日后上生产被外部查询请求打垮。

方案选择

针对限流措施,有基于Redis的滑动窗口方案,适合作用于集群的场景。考虑在生产环境中,k8s有扩容策略会自动拉起额外的pod,选择基于内存的限流方案,对每个pod的流量单独限流。最终采用引入Sentinel的aop与spring集成,达到限流目的。

操作步骤

1.引入Sentinel的相关maven依赖

<!--sentinel流控组件核心-->  
<dependency>  
    <groupId>com.alibaba.csp</groupId>  
    <artifactId>sentinel-core</artifactId>  
</dependency>  
  <!--sentinel流控组件-aop--> 
<dependency>  
    <groupId>com.alibaba.csp</groupId>  
    <artifactId>sentinel-annotation-aspectj</artifactId>  
</dependency>  
  <!--sentinel流控组件-热点参数--> 
<dependency>  
    <groupId>com.alibaba.csp</groupId>  
    <artifactId>sentinel-parameter-flow-control</artifactId>  
</dependency>

2.与springboot集成

将SentinelResourceAspect注册到spring容器中,使Sentinel生效

@Bean  
public SentinelResourceAspect sentinelResourceAspect(){  
    return new SentinelResourceAspect();  
}

在需要进行限流的方法上,使用@SentinelResource注解对资源名、降级、熔断处理进行配置

@SentinelResource(value = "queryLimit",blockHandler = "handlerCall")
@GetMapping("/query")
public String query(@RequstParam String paramA,@RequstParam String paramB){
    return "hello";
}

在同类中创建一个同返回值,同参数(额外增加一个BlockException类型参数接收限流触发的异常)的降级回调方法,方法名同blockHandler属性中一致

public String query(String paramA,String paramB,BlockException exception){
    return "error";
}

3.实现自定义的流控规则

在完成上述操作后,还需要定义自己的流控规则才能真正实现接口的限流。Sentinel提供了几种规则,详情可见官网文档,这里不多说明。结合我的业务场景,需要对不同商户发起的调用进行分别限流,所以我采用了热点参数规则,将商户ID的当做参数,针对请求频繁的商户进行限流处理。

ParamFlowRule rule = new ParamFlowRule(resourceName)
                    .setParamIdx(0)
                    .setCount(5); 
// 针对 int 类型的参数 PARAM_B,单独设置限流 QPS 阈值为 10,而不是全局的阈值 5. 
ParamFlowItem item = new ParamFlowItem()
                  .setObject(String.valueOf(PARAM_B))
                   .setClassType(int.class.getName()) 
                   .setCount(10); 
rule.setParamFlowItemList(Collections.singletonList(item)); 
ParamFlowRuleManager.loadRules(Collections.singletonList(rule));

image.png 如上,即可完成对不同商户进行限流处理

后记

为了方便动态更新QPS的限流值,qps的限流阈值配置到了nacos,在nacos更新阈值后,需要将新限流规则覆盖旧的规则。会在后续的文章中单独记录。