文档章节

Spring Cloud Gateway 原生的接口限流该怎么玩

冷冷gg
 冷冷gg
发布于 2018/07/02 06:25
字数 653
阅读 3999
收藏 1
关于pig:

基于Spring Cloud、oAuth2.0开发基于Vue前后分离的开发平台,支持账号、短信、SSO等多种登录,提供配套视频开发教程。

码云地址:https://gitee.com/log4j/pig

关于 Spring Cloud Gateway

SpringCloudGateway是Spring官方基于Spring 5.0,Spring Boot 2.0和Project Reactor等技术开发的网关,Spring云网关旨在提供一种简单而有效的路由API的方法。Spring Cloud Gateway作为Spring Cloud生态系中的网关,目标是替代Netflix ZUUL,其不仅提供统一的路由方式,并且基于Filter链的方式提供了网关基本的功能,例如:安全,监控/埋点,和限流等。

zuul如何实现多维度限流请参考我的博客

Zuul:构建高可用网关之多维度限流

开始Gateway 限流

POM 依赖

<!--spring cloud gateway依赖-->
<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-gateway</artifactId>
</dependency>
<!--基于 reactive stream 的redis -->
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-data-redis-reactive</artifactId>
</dependency>

配置按照请求IP 的限流

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

配置bean,多维度限流量的入口

/**
* 自定义限流标志的key,多个维度可以从这里入手
* exchange对象中获取服务ID、请求信息,用户信息等
*/
@Bean
KeyResolver remoteAddrKeyResolver() {
    return exchange -> Mono.just(exchange.getRequest().getRemoteAddress().getHostName());
}

OK 完成。

压力测试

并发5个线程。
image

Redis 数据变化

我们使用redis的monitor 命令,实时查看redis 的操作情况。
会发现在redis中会操作两个key

  • request_rate_limiter.{xxx}.timestamp
  • request_rate_limiter.{xxx}.tokens image

实现原理

image

Spring Cloud Gateway 默认实现 Redis限流,如果扩展只需要实现ratelimter接口即可。

RedisRateLimter 的核心代码,判断是否取到令牌的实现,通过调用 redis的LUA 脚本。

public Mono<Response> isAllowed(String routeId, String id) {
	Config routeConfig = getConfig().getOrDefault(routeId, defaultConfig);
	int replenishRate = routeConfig.getReplenishRate();
	int burstCapacity = routeConfig.getBurstCapacity();

	try {
		List<String> keys = getKeys(id);
		returns unixtime in seconds.
		List<String> scriptArgs = Arrays.asList(replenishRate + "", burstCapacity + "",
				Instant.now().getEpochSecond() + "", "1");
		// 这里是核心,执行redis 的LUA 脚本。
		Flux<List<Long>> flux =
		this.redisTemplate.execute(this.script, keys, scriptArgs);
		return flux.onErrorResume(throwable -> Flux.just(Arrays.asList(1L, -1L)))
				.reduce(new ArrayList<Long>(), (longs, l) -> {
					longs.addAll(l);
					return longs;
				}) .map(results -> {
					boolean allowed = results.get(0) == 1L;
					Long tokensLeft = results.get(1);

					Response response = new Response(allowed, getHeaders(routeConfig, tokensLeft));

					if (log.isDebugEnabled()) {
						log.debug("response: " + response);
					}
					return response;
				});
	}
	catch (Exception e) {
		log.error("Error determining if user allowed from redis", e);
	}
	return Mono.just(new Response(true, getHeaders(routeConfig, -1L)));
}

LUA 脚本

image

© 著作权归作者所有

共有 人打赏支持
冷冷gg
粉丝 444
博文 113
码字总数 52275
作品 1
潍坊
UI设计师
私信 提问
加载中

评论(10)

l
liulang382300
只有放一个网关么
fengymi
fengymi

引用来自“fengymi”的评论

这个压力测试的软件是啥

引用来自“冷冷gg”的评论

jmeter 4.0
好的,居然是黑色界面,我还以为其他啥工具
冷冷gg
冷冷gg

引用来自“fengymi”的评论

这个压力测试的软件是啥
jmeter 4.0
fengymi
fengymi
这个压力测试的软件是啥
w
willess
冷总威武哈哈😬
Big_BoBo
Big_BoBo
厉害
天籁111
天籁111
哟哟哟,不得了,赶紧来赞一个😏
momisabuilder
momisabuilder
爱吃大肉包
爱吃大肉包
还没用过,问下zuul的功能都有带过去么
O
OSC_iigkof
马克
Spring Cloud Gateway 限流操作

开发高并发系统时有三把利器用来保护系统:缓存、降级和限流,API网关作为所有请求的入口,请求量大,我们可以通过对并发访问的请求进行限速来保护系统的可用性。 常用的限流算法比如有令牌桶...

尹吉欢
2018/07/23
0
0
微服务网关Zuul迁移到Spring Cloud Gateway

背景 在之前的文章中,我们介绍过微服务网关Spring Cloud Netflix Zuul,前段时间有两篇文章专门介绍了Spring Cloud的全新项目Spring Cloud Gateway,以及其中的过滤器工厂。本文将会介绍将微...

aoho
2018/09/24
0
0
spring cloud gateway 之限流篇

版权声明:本文为博主原创文章,欢迎转载,转载请注明作者、原文超链接 ,博主地址:http://blog.csdn.net/forezp。 https://blog.csdn.net/forezp/article/details/85081162 转载请标明出处...

方志朋
2018/12/18
0
0
Spring Cloud 终于按捺不住推出了自己的服务网关 Gateway

Spring 官方最终还是按捺不住推出了自己的网关组件:Spring Cloud Gateway ,相比之前我们使用的 Zuul(1.x) 它有哪些优势呢?Zuul(1.x) 基于 Servlet,使用阻塞 API,它不支持任何长连接...

Java填坑路
2018/12/19
0
0
Spring Cloud Gateway 之Predict篇

版权声明:本文为博主原创文章,欢迎转载,转载请注明作者、原文超链接 ,博主地址:http://blog.csdn.net/forezp。 https://blog.csdn.net/forezp/article/details/84926662 转载请标明出处...

方志朋
2018/12/09
0
0

没有更多内容

加载失败,请刷新页面

加载更多

OSChina 周一乱弹 —— 白掌柜说了卖货不卖身

Osc乱弹歌单(2019)请戳(这里) 【今日歌曲】 @爱漫爱 :这是一场修行分享羽肿的单曲《Moony》 手机党少年们想听歌,请使劲儿戳(这里) @clouddyy :开不开心? 开心呀, 我又不爱睡懒觉…...

小小编辑
今天
9
0
大数据教程(11.7)hadoop2.9.1平台上仓库工具hive1.2.2搭建

上一篇文章介绍了hive2.3.4的搭建,然而这个版本已经不能稳定的支持mapreduce程序。本篇博主将分享hive1.2.2工具搭建全过程。先说明:本节就直接在上一节的hadoop环境中搭建了! 一、下载apa...

em_aaron
今天
3
0
开始看《JSP&Servlet学习笔记》

1:WEB应用简介。其中1.2.1对Web容器的工作流程写得不错 2:编写Servlet。搞清楚了Java的Web目录结构,以及Web.xml的一些配置作用。特别是讲了@WebServlet标签 3:请求与响应。更细致的讲了从...

max佩恩
今天
4
0
mysql分区功能详细介绍,以及实例

一,什么是数据库分区 前段时间写过一篇关于mysql分表的的文章,下面来说一下什么是数据库分区,以mysql为例。mysql数据库中的数据是以文件的形势存在磁盘上的,默认放在/mysql/data下面(可...

吴伟祥
今天
5
0
SQL语句查询

1.1 排序 通过order by语句,可以将查询出的结果进行排序。放置在select语句的最后。 格式: SELECT * FROM 表名 ORDER BY 排序字段ASC|DESC; ASC 升序 (默认) DESC 降序 1.查询所有商品信息,...

stars永恒
今天
5
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部