NIUCLOUD是一款SaaS管理后台框架多应用插件+云编译。上千名开发者、服务商正在积极拥抱开发者生态。欢迎开发者们免费入驻。一起助力发展! 广告
在前面的若干节内容中为大家介绍了sentinel流控规则的配置,只要我们正确的集成了sentinel客户端(核心库),我们几乎不需要做任何的代码开发。就可以实现应用服务限流。 ![](https://img.kancloud.cn/06/00/0600808b8e29d083c0060464b278eb3e_1082x160.png) 当请求并发达到限流的标准之后,我们再请求资源服务接口,就会得到上文中的响应结果。原始的响应结果实际包含了三部分内容: * HTTP状态码:429 too many request,太多的请求无法处理 * 提示信息:Blocked by Sentinel (flow limiting),请求被Sentinel的限流策略拦截 * 后台服务实际上抛出了BlockException(准确的说是FlowException继承自BlockException) 其实从笔者自身的实践来看,**把上面的原始的限流响应结果交给前端做一个统一的处理**,转换成友好的提示信息比如:“系统服务繁忙请稍后再试!”。**是非常好的做法:统一、简单、易维护!**但是java服务端也给出了BlockException(准确的说是FlowException继承自BlockException)响应的异常拦截处理方案,我们也有必要学习一下。以备适应更多的个性化场景。 ## 一、BlockHandler 如果我们希望请求被限流之后,给用户一些相对友好的信息,而不是Blocked by Sentinel (flow limiting);或者服务被限流之后做一些特殊的业务处理。我们需要通过SentinelResource注解的BlockHandler属性来实现。 ![](https://img.kancloud.cn/5e/30/5e30720be92d730f0b6e1c7cf454eec9_1514x431.png) * value:资源名称,必需项。需要注意的是:如果controller的mappingUrl是"/sysuser/pwd/reset",那么SentinelResource的value属性就不要再配置成"/sysuser/pwd/reset"。会导致异常等处理逻辑**偶尔失效**。 * blockHandler :当资源服务接口被限流之后,就执行该属性指定的方法。 * 对应处理 BlockException 的方法名称,可选项。 * blockHandler 方法修饰符必须是 public,返回类型需要与原方法相匹配。 * 参数类型需要和原方法相匹配并且最后加一个额外的参数,类型为 BlockException。 ![](https://img.kancloud.cn/87/00/8700b6977c94ad20a8408dcb330f8d2d_762x269.png) 上面的代码+控制台资源访问限流配置(QPS=1),然后我们使用Postman快速向"/sysuser/pwd/reset"发送请求,结果如下(不再是系统默认的限流响应信息,对于前端更加友好): ![](https://img.kancloud.cn/2e/10/2e10e445334cc4758a86801bcbed6076_362x130.png) ## 二、blockHandlerClass与BlockHandler搭配适用 按照上面的使用BlockHandler进行限流之后的异常处理,blockHandler 方法和项目的实际业务处理方法在一个类中,如果我们希望把限流处理方法独立出来,需要使用到blockHandlerClass。 我们可以把通用的blockHandler 异常处理方法单独抽取到一个类中 * 方法必须是static否则无法正确被解析 * 方法参数定义必须和实际业务处理方法一致,在此基础上新增一个BlockException参数 代码如下: ~~~ public class SysuserControllerHandler { public static AjaxResponse pwdresetBlockHandler(@RequestParam Integer userId, BlockException blockException) { return AjaxResponse.error(CustomExceptionType.SYSTEM_ERROR, "尊敬的客户您好,系统服务繁忙,请稍后再试!"); } } ~~~ 在实际的业务处理方法上,blockHandlerClass与BlockHandler搭配适用找到限流之后的处理方法。 ![](https://img.kancloud.cn/da/7b/da7b1e5f77689658f9aa574fd0052a51_1124x312.png) 上面的代码+控制台资源访问限流配置(QPS=1),然后我们使用Postman快速向"/sysuser/pwd/reset"发送请求,结果如下(不再是系统默认的限流响应信息,对于前端更加友好): ![](https://img.kancloud.cn/90/71/907155f4fb3cadf6c509bcd3f9ef134b_466x137.png) ## 三、总结 大家可以看到使用blockHandlerClass虽然可以达到实际业务处理方法与blockHandler 方法解耦目的,但是我们仍然需要几乎针对每一个函数进行限流方法的开发,因为每个方法的参数是不同的。**所以这些方法都只适用于个性化配置,不是全局配置。** 那么sentinel针对**服务限流**,有没有全局的默认的BlockHandler呢?**答案是没有(2020年5月)**。但是从笔者的实践来看这真的不影响什么,**把最原始的限流响应结果交给前端做一个统一的处理**,给出友好的提示信息比如:“系统服务繁忙请稍后再试!”。**是非常好的做法:统一、简单、易维护!**