hello,你好呀,我是灰小猿,一个超会写bug的程序员!
sentinel作为SpringCloudAlibaba的基本组件,在进行熔断、限流、降级等方面具有十分重要的作用,而且其基于Web界面对接口进行限流配置,使得实时监控接口流量,控制限流策略变得十分方便。
这篇文章和大家分享一下如何在对接口配置了限流规则后,使用自定义的配置实现触发限流后的返回结果和响应处理。
首先在sentinel界面对相应的接口添加一个限流策略,我配置的如下:一秒内限制接口请求量为2个。
限流的接口如下:
@RestController
public class ConsumeAController {
@GetMapping("/getInfo")
public String getConsumeInfo(){
return "你好,灰小猿!";
}
}
对接口发起请求,正常情况下相应结果为:
当请求量达到限流规则后,在不配置自定义返回结果的情况下,sentinel默认的返回如下:
当然一般情况下我们需要给前端返回一个具体的相应处理结果,所以就需要我们对触发限流后的响应进行自定义配置。
sentinel进行限流处理默认方法为:
public class DefaultBlockExceptionHandler implements BlockExceptionHandler {
public DefaultBlockExceptionHandler() {
}
public void handle(HttpServletRequest request, HttpServletResponse response, BlockException e) throws Exception {
response.setStatus(429);
PrintWriter out = response.getWriter();
out.print("Blocked by Sentinel (flow limiting)");
out.flush();
out.close();
}
}
如果想要实现自定义的配置,只需要重新实现BlockExceptionHandler 接口即可:
因为sentinel的限流规则从控制台可以看出有如下五种:
因此针对每种限流规则,可以设置分别返回不同的响应结果。每一种限流策略都对应了一种异常。我的配置类如下:
注:在下面的自定义类中,如果不需要返回自定义的响应结果,而是跳转到对应页面,可以将返回结果处理换成方法中最后的两种处理方法即可。
/**
* 自定义配置限流降级错误信息
*/
@Slf4j
@Component
public class MyBlockExceptionHandler implements BlockExceptionHandler {
@Override
public void handle(HttpServletRequest request, HttpServletResponse response, BlockException e) throws Exception {
ResultObject resultObject = null;
//根据限流降级的策略规则,不同的异常返回不同的提示语,
if (e instanceof FlowException) {
resultObject = ResultObject.builder().code(100).message("接口限流了").build();
}else if (e instanceof DegradeException){
resultObject = ResultObject.builder().code(101).message("服务降级了").build();
}else if (e instanceof ParamFlowException){
resultObject = ResultObject.builder().code(102).message("热点参数限流了").build();
}else if (e instanceof SystemBlockException){
resultObject = ResultObject.builder().code(103).message("触发系统保护规则了").build();
}else if(e instanceof AuthorityException){
resultObject = ResultObject.builder().code(104).message("授权规则不通过").build();
}
response.setStatus(HttpStatus.INTERNAL_SERVER_ERROR.value());
response.setCharacterEncoding("utf-8");
response.setContentType(MediaType.APPLICATION_JSON_VALUE);
new ObjectMapper().writeValue(response.getWriter(),resultObject);
//如果需要跳转到指定页面使用如下处理:
//request.getRequestDispatcher("/index.jsp").forward(request,response);
//跳转到网站
//response.sendRedirect("https://blog.csdn.net/weixin_44985880");
}
}
其中的ResultObject为我自定义的统一返回结果类
/**
* 统一返回结果
*/
@Data
@AllArgsConstructor
@NoArgsConstructor
@Builder //生成构建器模式
public class ResultObject implements Serializable {
private Integer code;
private String message;
private Object data;
}
重新启动项目运行,多次刷新接口,触发限流策略后界面响应结果为:
至此,自定义限流处理成功!
我是灰小猿,我们下期见!