Sentinel限流实战
一,应用场景:开放平台提供url给第三方调用时,针对调用方请求进行限流,实现对ip和参数进行限流
两种实现方式
1,对SentinelGatewayBlockExceptionHandler进行改造,新创建一个该类,重写里面的返回方法
可参考:http://www.cppcns.com/ruanjian/java/257764.html
@Bean @Order(Ordered.HIGHEST_PRECEDENCE) public SentinelGatewayBlockExceptionHandler sentinelGatewayBlockExceptionHandler() {// Register the block exception handler for Spring Cloud Gateway.return new SentinelGatewayBlockExceptionHandler(viewResolvers, serverCodecConfigurer); }
2,平台实现,自定义响应处理类,实现BlockRequestHandler接口,包装返回信息,初始化调用自定义响应处理类
参考:https://blog.csdn.net/developlee/article/details/100987345
您可以在 GatewayCallbackManager
注册回调进行定制:
setBlockHandler
:注册函数用于实现自定义的逻辑处理被限流的请求,对应接口为BlockRequestHandler
。默认实现为DefaultBlockRequestHandler
,当被限流时会返回类似于下面的错误信息:Blocked by Sentinel: FlowException
。
二,代码实现,改造SentinelGatewayBlockExceptionHandler
1,Sentinel配置类
/*** sentinel配置** @author lr* @date 2019-09-12 13:31*/
@Configuration
public class SentinelGatewayConfiguration {@Autowiredprivate InetUtils inetUtils;private final List<ViewResolver> viewResolvers;private final ServerCodecConfigurer serverCodecConfigurer;public SentinelGatewayConfiguration(ObjectProvider<List<ViewResolver>> viewResolversProvider,ServerCodecConfigurer serverCodecConfigurer) {this.viewResolvers = viewResolversProvider.getIfAvailable(Collections::emptyList);this.serverCodecConfigurer = serverCodecConfigurer;}// @Bean
// @Order(Ordered.HIGHEST_PRECEDENCE)
// public SentinelGatewayBlockExceptionHandler sentinelGatewayBlockExceptionHandler() {
// // Register the block exception handler for Spring Cloud Gateway.
// return new SentinelGatewayBlockExceptionHandler(viewResolvers, serverCodecConfigurer);
// }/*** 自定义响应参数** @return*/@Bean@Order(Ordered.HIGHEST_PRECEDENCE)public JsonSentinelGatewayBlockExceptionHandler jsonSentinelGatewayBlockExceptionHandler() {return new JsonSentinelGatewayBlockExceptionHandler(viewResolvers, serverCodecConfigurer);}@Bean@Order(-1)public GlobalFilter sentinelGatewayFilter() {return new SentinelGatewayFilter();}@PostConstructpublic void doInit() {initGatewayRules();//GatewayCallbackManager.setBlockHandler(new OpenBlockRequestHandler());//设置监控ip(多网卡时默认获取有问题,所以需要采用springCloud网卡工具类)SentinelConfig.setConfig(TransportConfig.HEARTBEAT_CLIENT_IP, inetUtils.findFirstNonLoopbackAddress().getHostAddress());}/*** 初始化路由规则*/private void initGatewayRules() {Set<GatewayFlowRule> rules = new HashSet<>();//限制每个ip每秒只能调用5次,//setBurst突发请求额外增加5个rules.add(new GatewayFlowRule("open_gateway").setCount(5).setIntervalSec(1).setBurst(5).setParamItem(new GatewayParamFlowItem().setParseStrategy(SentinelGatewayConstants.PARAM_PARSE_STRATEGY_CLIENT_IP)));//限制一个应用appId每秒只能调用5次//setBurst突发请求额外增加5个rules.add(new GatewayFlowRule("open_gateway").setCount(5).setIntervalSec(1).setBurst(5).setParamItem(new GatewayParamFlowItem().setParseStrategy(SentinelGatewayConstants.PARAM_PARSE_STRATEGY_URL_PARAM).setFieldName("appId")));//限制一个应用appId每秒只能调用5次//setBurst突发请求额外增加5个rules.add(new GatewayFlowRule("open_gateway").setCount(5).setIntervalSec(1).setBurst(5).setParamItem(new GatewayParamFlowItem().setParseStrategy(SentinelGatewayConstants.PARAM_PARSE_STRATEGY_URL_PARAM).setFieldName("appId").setPattern("testApp")));GatewayRuleManager.loadRules(rules);}
}
2,自定义响应类
public class JsonSentinelGatewayBlockExceptionHandler implements WebExceptionHandler {private List<ViewResolver> viewResolvers;private List<HttpMessageWriter<?>> messageWriters;private final Supplier<ServerResponse.Context> contextSupplier = () -> {return new ServerResponse.Context() {public List<HttpMessageWriter<?>> messageWriters() {return JsonSentinelGatewayBlockExceptionHandler.this.messageWriters;}public List<ViewResolver> viewResolvers() {return JsonSentinelGatewayBlockExceptionHandler.this.viewResolvers;}};};public JsonSentinelGatewayBlockExceptionHandler(List<ViewResolver> viewResolvers, ServerCodecConfigurer serverCodecConfigurer) {this.viewResolvers = viewResolvers;this.messageWriters = serverCodecConfigurer.getWriters();}private Mono<Void> writeResponse(ServerResponse response, ServerWebExchange exchange) {ServerHttpResponse serverHttpResponse = exchange.getResponse();serverHttpResponse.getHeaders().add("Content-Type", "application/json;charset=UTF-8");JSONObject responseObj = new JSONObject();responseObj.put("code", 403);responseObj.put("msg", "请求过于频繁,请稍后重试");byte[] datas = responseObj.toString().getBytes(StandardCharsets.UTF_8);DataBuffer buffer = serverHttpResponse.bufferFactory().wrap(datas);return serverHttpResponse.writeWith(Mono.just(buffer));}public Mono<Void> handle(ServerWebExchange exchange, Throwable ex) {if (exchange.getResponse().isCommitted()) {return Mono.error(ex);} else {return !BlockException.isBlockException(ex) ? Mono.error(ex) : this.handleBlockedRequest(exchange, ex).flatMap((response) -> {return this.writeResponse(response, exchange);});}}private Mono<ServerResponse> handleBlockedRequest(ServerWebExchange exchange, Throwable throwable) {return GatewayCallbackManager.getBlockHandler().handleRequest(exchange, throwable);}}
三,代码实现,GatewayCallbackManager
回调
1,Sentinel配置类
/*** sentinel配置** @author lr* @date 2019-09-12 13:31*/
@Configuration
public class SentinelGatewayConfiguration {@Autowiredprivate InetUtils inetUtils;private final List<ViewResolver> viewResolvers;private final ServerCodecConfigurer serverCodecConfigurer;public SentinelGatewayConfiguration(ObjectProvider<List<ViewResolver>> viewResolversProvider,ServerCodecConfigurer serverCodecConfigurer) {this.viewResolvers = viewResolversProvider.getIfAvailable(Collections::emptyList);this.serverCodecConfigurer = serverCodecConfigurer;}@Bean@Order(Ordered.HIGHEST_PRECEDENCE)public SentinelGatewayBlockExceptionHandler sentinelGatewayBlockExceptionHandler() {// Register the block exception handler for Spring Cloud Gateway.return new SentinelGatewayBlockExceptionHandler(viewResolvers, serverCodecConfigurer);}/*** 自定义响应参数** @return*/
// @Bean
// @Order(Ordered.HIGHEST_PRECEDENCE)
// public JsonSentinelGatewayBlockExceptionHandler jsonSentinelGatewayBlockExceptionHandler() {
// return new JsonSentinelGatewayBlockExceptionHandler(viewResolvers, serverCodecConfigurer);
// }@Bean@Order(-1)public GlobalFilter sentinelGatewayFilter() {return new SentinelGatewayFilter();}@PostConstructpublic void doInit() {initGatewayRules();GatewayCallbackManager.setBlockHandler(new OpenBlockRequestHandler());//设置监控ip(多网卡时默认获取有问题,所以需要采用springCloud网卡工具类)SentinelConfig.setConfig(TransportConfig.HEARTBEAT_CLIENT_IP, inetUtils.findFirstNonLoopbackAddress().getHostAddress());}/*** 初始化路由规则*/private void initGatewayRules() {Set<GatewayFlowRule> rules = new HashSet<>();//限制每个ip每秒只能调用5次,//setBurst突发请求额外增加5个rules.add(new GatewayFlowRule("open_gateway").setCount(5).setIntervalSec(1).setBurst(5).setParamItem(new GatewayParamFlowItem().setParseStrategy(SentinelGatewayConstants.PARAM_PARSE_STRATEGY_CLIENT_IP)));//限制一个应用appId每秒只能调用5次//setBurst突发请求额外增加5个rules.add(new GatewayFlowRule("open_gateway").setCount(5).setIntervalSec(1).setBurst(5).setParamItem(new GatewayParamFlowItem().setParseStrategy(SentinelGatewayConstants.PARAM_PARSE_STRATEGY_URL_PARAM).setFieldName("appId")));//限制一个应用appId每秒只能调用5次//setBurst突发请求额外增加5个rules.add(new GatewayFlowRule("open_gateway").setCount(5).setIntervalSec(1).setBurst(5).setParamItem(new GatewayParamFlowItem().setParseStrategy(SentinelGatewayConstants.PARAM_PARSE_STRATEGY_URL_PARAM).setFieldName("appId").setPattern("testApp")));GatewayRuleManager.loadRules(rules);}
}
2,自定义响应消息类
/*** @author lr* @date 2019-09-12 15:15*/
public class OpenBlockRequestHandler implements BlockRequestHandler {@Overridepublic Mono<ServerResponse> handleRequest(ServerWebExchange exchange, Throwable ex) {// JSON result by default.return ServerResponse.status(HttpStatus.OK).contentType(MediaType.APPLICATION_JSON_UTF8).body(fromObject(buildErrorResult(ex)));}private ResponseBean buildErrorResult(Throwable ex) {return ResponseBeanUtils.getResponseBean(ErrorCode.REQUEST_QPS_LIMIT_ERROR);}
}
四,postman调用结果
Sentinel限流实战相关推荐
- Sentinel整合Dubbo限流实战
Sentinel整合Dubbo限流实战 创建provider项目 添加jar依赖 <dependency><artifactId>sentinel-api</artifa ...
- Alibaba Sentinel限流功能
以下文章来源方志朋的博客,回复"666"获面试宝典 前言 上周经历了合作方未按照约定在客户端进行缓存,以高QPS调用我这边某个接口的问题,当时带来的影响是接口RT变高,当时如果QP ...
- Sentinel限流熔断
Sentinel作用:当我们 在系统负载过高时,可以通过Sentinel进行限流.降级.熔断三种措施来保护系统其提供了一个轻量级的控制台,提供机器发现,单机资源实时监控预计规则管理等功能. Senti ...
- sentinel限流入门
为什么限流 前端时间遇到的一次大型故障:订单服务应查询量巨大拖垮服务,导致公司核心系统系统瘫痪.那么如何避免此类事情再次发生,公司内部做了大量的服务下线或者尽可能减少服务调用的工作:除此之外,服务提供 ...
- Sentinel限流规则使用总结
文章目录 一.Sentinel限流/熔断规则 二.网关限流原理 三.自问自答QA 四.总结 一.Sentinel限流/熔断规则 目前Sentinel支持以下五种限流/熔断规则:基于资源限流(FlowR ...
- Sentinel 限流原理
Sentinel 限流原理 一.限流规则 在Sentinel中,限流的直接表现形式是,在执行Entry nodeA =SphU.entry(resourceName) 的时候抛出 FlowExcept ...
- 三、Sentinel限流熔断
Sentinel限流熔断 文章目录 Sentinel限流熔断 一.Sentinel简介 1. 背景分析 2. Sentinel概述 3. 安装Sentinel服务 4. 访问Sentinal服务 二. ...
- SpringCloudSpringCloud Alibaba、微服务架构、网站架构演变过程、Nacos、Feign远程调用、Load Balancer负载均衡、Sentinel限流、Hystriy
什么是微服务? 微服务架构就是将单体的应用程序分成多个应用程序,这多个应用程序就成为微服务,每个微服务运行在自己的进程中,并使用轻量级的机制通信.这些服务围绕业务能力来划分,并通过自动化部署机制来独立 ...
- Sentinel限流及其滑动窗口算法
Sentinel限流及其滑动窗口算法 Sentinel的限流原理 滑动时间窗口算法 Sentinel的限流原理 限流效果,对应有DefaultController快速失败 WarmUpControll ...
- 构建SpringCloud 项目初始环境(四)—Sentinel限流熔断应用实践
一.Sentinel简介 1.背景分析 在我们日常生活中,经常会在淘宝.天猫.京东.拼多多等平台上参与商品的秒杀.抢购以及一些优惠活动,也会在节假日使用12306 手机APP抢火车票.高铁票,甚至有时 ...
最新文章
- 《C#精彩实例教程》小组阅读07 -- C#字符与字符串
- aspx页面与ascx控件脚本冲突的问题
- 2021牛客多校10 - Train Wreck(贪心)
- spring 整合mongodb报NoSuchMethodError错误
- 今日代码(200624)--缺失值处理
- 红帽 jboss_红帽峰会2015所需的JBoss BPM内容指南
- Oracle学习笔记:通过种子数据库设置dbid为指定值
- 文档转换乱码异常解决:unoconv openoffice libreoffice
- Vue_eslint编码规范检查---vue工作笔记0021
- IntelliJ IDEA for CleanCode
- ssr的pac中加入学校图书馆数据库访问pac
- 为什么我的QQ会被冻结?
- python表格多列合并_python怎么批量合并excel表格
- matlab中imag什么意思,Matlab基本函数-imag函数
- 3dsmax建模总结
- word 编辑过程中变为只读_Word字体无法更改设置不起作用的几种情况
- 电脑主机需要清洁么,多久清理一次比较好?
- Word2007 表格换页自动“续表”方法
- 这届年轻人,怎么开始想着吃零食减肥了?
- 利用Office Online 实现文档在线预览
热门文章
- Android ProGuard 代码压缩混淆与打包优化
- nginx 逻辑运算
- 从Ibatis过渡到Mybatis-比较Mybaits较与Ibatis有哪些方面的改进
- MacDev.GarbageCollectionIsDeprecated-WhenXcodeCompileMacAppProject
- LINUX占用太多内存的解决方法
- ibatis学习(一)--ibatis介绍以及用例 [转]
- go srs 流媒体服务器_SRS-开源流媒体服务器
- gdb调试出现“no debugging symbols found”
- centos6.5 gcc升级至4.8
- Linux下5种动态库运行时搜索路径的方法