Spring Cloud Zuul微服务网关的API限流(转)


https://blog.csdn.net/ta_ab/article/details/77984312

API限流

微服务开发中有时需要对API做限流保护,防止网络攻击,比如做一个短信验证码API,限制客户端的请求速率能在一定程度上抵御短信轰炸攻击,降低损失。

微服务网关是每个请求的必经入口,非常适合做一些API限流、认证之类的操作,这里有一个基于zuul微服务网关的API限流库:

https://github.com/marcosbarbero/spring-cloud-zuul-ratelimit

使用方法

比如我们要对user-service这个服务进行限流,限制每个请求源每分钟最多只能请求10次。

首先在项目中添加 spring-cloud-zuul-ratelimit 依赖:

<dependency> <groupId>com.marcosbarbero.cloud</groupId> <artifactId>spring-cloud-zuul-ratelimit</artifactId> <version>1.5.0.RELEASE</version> </dependency>
  • 1
  • 2
  • 3
  • 4
  • 5

然后再添加如下配置即可:

zuul:
  ratelimit:
    enabled: true
    behind-proxy: true
    policy-list:
      user-service:
        - limit: 10 refresh-interval: 60 type: - user - origin - url
  • 测试客户端如果60s内请求超过10次,服务端就抛出异常,一分钟后又可以正常请求

  • 某个IP的客户端被限流并不影响其他客户端,即API网关对每个客户端限流是相互独立的

限流数据存储

对API限流是基于Zuul过滤器完成的,默认情况下限流数据是记录在内存中的,实际上是用ConcurrentHashMap保存,当然也提供了多种存储方式,包括Redis、Consul、Spring Data JPA,使用这三种存储方式要添加相关依赖。

然后再添加存储配置,比如使用Redis的配置:

zuul: ratelimit: repository: Redis
  • 1
  • 2
  • 3

原理分析

限流拦截时机

限流过滤器是在请求被转发之前调用的

    @Override public String filterType() { return "pre"; }

 

限流类型

限流类型主要包括url、origin、user三种

   if (types.contains(URL)) { joiner.add(route.getPath()); } if (types.contains(ORIGIN)) { joiner.add(getRemoteAddr(request)); } if (types.contains(USER)) { joiner.add(request.getUserPrincipal() != null ? request.getUserPrincipal().getName() : ANONYMOUS); }
  • url类型的限流就是通过请求路径区分

  • origin是通过客户端IP地址区分

  • user是通过授权用户进行区分,也包括匿名用户

  • 可以多个限流类型结合使用

  • 如果不配置限流类型,就不做以上区分

拦截限流请求

在过滤器的run方法中判断请求剩余次数,小于0就拦截请求:

   if (rate.getRemaining() < 0) { ctx.setResponseStatusCode(TOO_MANY_REQUESTS.value()); ctx.put("rateLimitExceeded", "true"); throw new ZuulRuntimeException(new ZuulException(TOO_MANY_REQUESTS.toString(), TOO_MANY_REQUESTS.value(), null)); }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6

可以看到,单位时间内剩余请求次数小于0时抛出ZuulRuntimeException,直接返回客户端TOO_MANY_REQUESTS异常消息,达到拦截请求的效果。

示例代码

https://github.com/yunTerry/spring-cloud-netflix


免责声明!

本站转载的文章为个人学习借鉴使用,本站对版权不负任何法律责任。如果侵犯了您的隐私权益,请联系本站邮箱yoyou2525@163.com删除。



 
粤ICP备18138465号  © 2018-2025 CODEPRJ.COM