之前分享过 一篇 《Spring Cloud Gateway 原生的接口限流该怎么玩》, 核心是依赖Spring Cloud Gateway 默认提供的限流过滤器来实现

原生RequestRateLimiter 的不足

  • 配置方式
spring:
cloud:
gateway:
routes:
- id: requestratelimiter_route
uri: lb://pigx-upms
order: 10000
predicates:
- Path=/admin/**
filters:
- name: RequestRateLimiter
args:
redis-rate-limiter.replenishRate: 1
redis-rate-limiter.burstCapacity: 3
key-resolver: "#{@remoteAddrKeyResolver}" #SPEL表达式去的对应的bean
- StripPrefix=1
  • RequestRateLimiterGatewayFilterFactory
public GatewayFilter apply(Config config) {
KeyResolver resolver = getOrDefault(config.keyResolver, defaultKeyResolver);
RateLimiter<Object> limiter = getOrDefault(config.rateLimiter,
defaultRateLimiter);
boolean denyEmpty = getOrDefault(config.denyEmptyKey, this.denyEmptyKey);
HttpStatusHolder emptyKeyStatus = HttpStatusHolder
.parse(getOrDefault(config.emptyKeyStatus, this.emptyKeyStatusCode)); return (exchange, chain) -> {
return exchange.getResponse().setComplete();
});
});
};
}
  • 在实际生产过程中,必定不能满足我们的需求

    生产中路由信息是保存数据库持久化或者配置中心,RequestRateLimiterGatewayFilterFactory 并不能随着持久化数据的改变而动态改变限流参数,不能做到实时根据流量来改变流量阈值

Sentinel Spring Cloud Gateway 流控支持

Sentinel 是什么?

随着微服务的流行,服务和服务之间的稳定性变得越来越重要。Sentinel 以流量为切入点,从流量控制、熔断降级、系统负载保护等多个维度保护服务的稳定性,分布式系统的流量防卫兵。

从 1.6.0 版本开始,Sentinel 提供了 Spring Cloud Gateway 的适配模块,可以提供两种资源维度的限流:

route 维度:即在 Spring 配置文件中配置的路由条目,资源名为对应的 routeId

自定义 API 维度:用户可以利用 Sentinel 提供的 API 来自定义一些 API 分组

pom 依赖

<!--Spring Cloud Alibaba 封装的 sentinel 模块-->
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-alibaba-sentinel-gateway</artifactId>
</dependency> <!--使用nacos 保存限流规则-->
<dependency>
<groupId>com.alibaba.csp</groupId>
<artifactId>sentinel-datasource-nacos</artifactId>
</dependency>

配置本地路由规则及其sentinel数据源

spring:
application:
name: sentinel-spring-cloud-gateway
cloud:
gateway:
enabled: true
discovery:
locator:
lower-case-service-id: true
routes:
- id: pigx_route
uri: https://api.readhub.cn
predicates:
- Path=/topic/**
sentinel:
datasource.ds1.nacos:
server-addr: 127.0.0.1:8848
data-id: gw-flow
group-id: DEFAULT_GROUP
ruleType: gw-api-group
filter:
enabled: true

配置nacos数据源中的限流策略

  • 常用限流策略 常量
以客户端IP作为限流因子
public static final int PARAM_PARSE_STRATEGY_CLIENT_IP = 0;
以客户端HOST作为限流因子
public static final int PARAM_PARSE_STRATEGY_HOST = 1;
以客户端HEADER参数作为限流因子
public static final int PARAM_PARSE_STRATEGY_HEADER = 2;
以客户端请求参数作为限流因子
public static final int PARAM_PARSE_STRATEGY_URL_PARAM = 3;
以客户端请求Cookie作为限流因子
public static final int PARAM_PARSE_STRATEGY_COOKIE = 4;
  • 核心源码解析 SentinelGatewayFilter

sentinel通过扩展Gateway的过滤器,通过选择的不同GatewayParamParser 过处理请求限流因子和数据源中的配置进行比较

源码如下:

public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
Route route = exchange.getAttribute(ServerWebExchangeUtils.GATEWAY_ROUTE_ATTR); Mono<Void> asyncResult = chain.filter(exchange);
if (route != null) {
String routeId = route.getId();
Object[] params = paramParser.parseParameterFor(routeId, exchange,
r -> r.getResourceMode() == SentinelGatewayConstants.RESOURCE_MODE_ROUTE_ID);
String origin = Optional.ofNullable(GatewayCallbackManager.getRequestOriginParser())
.map(f -> f.apply(exchange))
.orElse("");
asyncResult = asyncResult.transform(
new SentinelReactorTransformer<>(new EntryConfig(routeId, EntryType.IN,
1, params, new ContextConfig(contextName(routeId), origin)))
);
} Set<String> matchingApis = pickMatchingApiDefinitions(exchange);
for (String apiName : matchingApis) {
Object[] params = paramParser.parseParameterFor(apiName, exchange,
r -> r.getResourceMode() == SentinelGatewayConstants.RESOURCE_MODE_CUSTOM_API_NAME);
asyncResult = asyncResult.transform(
new SentinelReactorTransformer<>(new EntryConfig(apiName, EntryType.IN, 1, params))
);
} return asyncResult;
}

效果演示

  • 以上nacos 配置为 每秒只能通过5个请求,我们使用jmeter 4.0 来并发10个线程测试一下





  • 通过上图可以结果证明sentinel限流确实有效

动态修改限流参数

  • sentinel-datasource-nacos 作为sentinel的数据源,可以从如上 nacos 管理台实时刷新限流参数及其阈值
  • 目前sentinel dashboard 1.6.2 暂未实现gateway 流控图形化控制 , 1.7.0 会增加此功能

总结

欢迎关注我们获得更多的好玩JavaEE 实践

项目推荐: Spring Cloud 、Spring Security OAuth2的RBAC权限管理系统 欢迎关注

Spring Cloud Gateway 扩展支持动态限流的更多相关文章

  1. Spring Cloud Gateway 结合配置中心限流

    前言 上篇文章我讲过复杂的限流场景可以通过扩展RedisRateLimiter来实现自己的限流策略. 假设你领导给你安排了一个任务,具体需求如下: 针对具体的接口做限流 不同接口限流的力度可以不同 可 ...

  2. Spring Cloud gateway 网关四 动态路由

    微服务当前这么火爆的程度,如果不能学会一种微服务框架技术.怎么能升职加薪,增加简历的筹码?spring cloud 和 Dubbo 需要单独学习.说没有时间?没有精力?要学俩个框架?而Spring C ...

  3. Spring Cloud实践:降级、限流、滚动、灰度、AB、金丝雀的实现思路

    端口:8888,方便起见直接读取配置文件,生产环境可以读取git.application-dev.properties为全局配置.先启动配置中心,所有服务的配置(包括注册中心的地址)均从配置中心读取. ...

  4. spring cloud网关通过Zuul RateLimit 限流配置

    目录 引入依赖 配置信息 RateLimit源码简单分析 RateLimit详细的配置信息解读 在平常项目中为了防止一些没有token访问的API被大量无限的调用,需要对一些服务进行API限流.就好比 ...

  5. Spring Cloud微服务Sentinel+Apollo限流、熔断实战总结

    在Spring Cloud微服务体系中,由于限流熔断组件Hystrix开源版本不在维护,因此国内不少有类似需求的公司已经将眼光转向阿里开源的Sentinel框架.而以下要介绍的正是作者最近两个月的真实 ...

  6. spring cloud gateway 之限流篇

    转载请标明出处: https://www.fangzhipeng.com 本文出自方志朋的博客 在高并发的系统中,往往需要在系统中做限流,一方面是为了防止大量的请求使服务器过载,导致服务不可用,另一方 ...

  7. 微服务网关实战——Spring Cloud Gateway

    导读 作为Netflix Zuul的替代者,Spring Cloud Gateway是一款非常实用的微服务网关,在Spring Cloud微服务架构体系中发挥非常大的作用.本文对Spring Clou ...

  8. springcloud3(五) spring cloud gateway动态路由的四类实现方式

    写这篇博客主要是为了汇总下动态路由的多种实现方式,没有好坏之分,任何的方案都是依赖业务场景需求的,现在网上实现方式主要有: 基于Nacos, 基于数据库(PosgreSQL/Redis), 基于Mem ...

  9. Spring Cloud gateway 六 Sentinel nacos存储动态刷新

    微服务当前这么火爆的程度,如果不能学会一种微服务框架技术.怎么能升职加薪,增加简历的筹码?spring cloud 和 Dubbo 需要单独学习.说没有时间?没有精力?要学俩个框架?而Spring C ...

随机推荐

  1. AtCoder Regular Contest 113

    比赛地址 A(暴力) 题目链接 题目: 给出\(K\),求出满足\(A\times B\times C\le K\)的\((A,B,C)\)对数 解析: 将C移动到等式右边,得到\(A\times B ...

  2. 图片居中的flex实现

    文本居中 text-align:center; 如果是图片放在div中,就没办法了.用flex可以很简单实现. display: flex; justify-content: center; /* 图 ...

  3. ElasticSearch DSL 查询

    公号:码农充电站pro 主页:https://codeshellme.github.io DSL(Domain Specific Language)查询也叫做 Request Body 查询,它比 U ...

  4. short i=1;i=i+1;为什么报错?

    先测试,看结果: 提示我们说不能将short类型的转化为int类型! 先不急着下结论,我们继续测试,用i+=1; 我们发现并没有报错,为什么同样是加1,会出现这样两种不同的结果呢? 查阅了一些资料,大 ...

  5. ctf.show_web13(文件上传之.user.ini)

    这是一道文件上传题,先二话不说丢个图片码,显示为 先考虑文件太小,用burp抓包,添加了一堆无用的东西后显示仍然是error file zise,直到上传正常图片依旧如此,考虑文件太大.将一句话木马修 ...

  6. Android中Context样式分析

    目录 1.样式定义以及使用 1.1.默认样式 1.2.样式定义及使用 1.3.当前样式下attr属性的获取 1.4.属性集合的定义与获取 2.Activity中Theme的初始化流程 2.1.系统调用 ...

  7. PCA——主成分分析

    PCA(Principal Components Analysis)主成分分析是一个简单的机器学习算法,利用正交变换把由线性相关变量表示的观测数据转换为由少量线性无关比变量表示的数据,实现降维的同时尽 ...

  8. 阿里的Easyexcel读取Excel文件(最新版本)

      本篇文章主要介绍一下使用阿里开源的Easyexcel工具处理读取excel文件,因为之前自己想在网上找一下这个简单的立即上手的博客,发现很多文章的教程都针对比较旧的版本的Easyexcel,没有使 ...

  9. Excel查分系统搭建小技巧

    推荐一个教师必备工具"Yichafen",是一个在线查分系统,全国8000所高校都在用,三分钟极速创建发布查分系统 在工作学习中,我们经常会遇到查分系统这样的问题.培根说过:读书足 ...

  10. Java传参:值传递 or 引用传递 ?

    刚开始学Java的时候一度以为:基本数据类型是值传递,引用类型是引用传递.新人很容易在这两个概念上面被搞糊涂,后来看了Hollis的文章才明白了Java中只有值传递. 接下来我能用简单明了的方式来说明 ...