接口测试怎么做限流_Spring Cloud Gateway原生的接口限流该怎么玩?

65e5e0abaafdd1ea47b5a4e975d72566.png
作者:冷冷zz 来源:https://my.oschina.net/giegie/blog/1838560

# 关于 Spring Cloud Gateway

SpringCloudGateway是Spring官方基于Spring 5.0,Spring Boot 2.0和Project Reactor等技术开发的网关,Spring云网关旨在提供一种简单而有效的路由API的方法。

Spring Cloud Gateway作为Spring Cloud生态系中的网关,目标是替代Netflix ZUUL,其不仅提供统一的路由方式,并且基于Filter链的方式提供了网关基本的功能,例如:安全,监控/埋点,和限流等。

# 开始Gateway 限流

POM 依赖
    org.springframework.cloud    spring-cloud-starter-gateway    org.springframework.boot    spring-boot-starter-data-redis-reactive
配置按照请求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、请求信息,用户信息等*/@BeanKeyResolver remoteAddrKeyResolver() {    return exchange -> Mono.just(exchange.getRequest().getRemoteAddress().getHostName());}

OK 完成。

压力测试

并发5个线程。570e94cc3bd41fb7dd96b8dee5b26ef7.png

Redis 数据变化

我们使用redis的monitor 命令,实时查看redis 的操作情况。


会发现在redis中会操作两个key

  • request_rate_limiter.{xxx}.timestamp

  • request_rate_limiter.{xxx}.tokens 

30f2b7e029c6ac6a0dafeb26dbb694a0.png

# 实现原理

2226d809635436d00c4cc507359f7f64.png

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

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

public Mono isAllowed(String routeId, String id) {  Config routeConfig = getConfig().getOrDefault(routeId, defaultConfig);  int replenishRate = routeConfig.getReplenishRate();  int burstCapacity = routeConfig.getBurstCapacity();  try {    List keys = getKeys(id);    returns unixtime in seconds.    List scriptArgs = Arrays.asList(replenishRate + "", burstCapacity + "",        Instant.now().getEpochSecond() + "", "1");    // 这里是核心,执行redis 的LUA 脚本。    FluxLong>> 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 脚本

aa42b9c9b92864559935472883e3b731.png

2f9d42b7c13bc6c386dba583035771c6.png热门推荐:

  • 牛皮!竟然可以用程序修改支付宝(微信)运动步数,横扫榜单~
  • 免费版的 IDEA 为啥不能使用 Tomcat ?
  • 新媒体管家插件被百度告了,永久停服了~
6f1c16482b1619b1118c07fe35f9e531.png

最后,推荐给大家一个有趣有料的公众号:程序员Tools,该公众号主要为大家分享有趣有料的开发者工具,还有老鬼给你带路,永不迷路~

4e54c0577907201934eb349942e50b62.png

扫描关注,永不迷路

08f0174df5fb1fce1569801e9b696d05.gif 点击
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值