Zuul网关优化实践之限流

为了防止网关过量负载请求,很多时候会要根据实际的情况对接口进行限流。zuul本身是没有提供限流的功能的,但是你也可以根据它提供的filter自己去做限流,当然也可以使用人家已经写好了的限流组件去集成,因为资源有限,自研成本会很高,所以还是采取集成别人的功能来做,然后根据看一下人家的代码和自身业务做结合去达到最终的目的。

需求功能

  • 全局的限流
  • 特定URL限流、希望是可配置
    • 有些业务复杂,耗费资源的需要单独配置限流规则。
    • 可以做个类似于防重提交的功能
      • 比如1秒内某个接口只能点击一次。

开源限流工具

spring-cloud-zuul-ratelimit

基于Zuul的filter开发的限流功能,可以结合本地缓存、redis、consul、mysql等做数据存储。
配置简单、使用方便
接下来我们先集成该工具

maven配置
<dependency>
    <groupId>com.marcosbarbero.cloud</groupId>
    <artifactId>spring-cloud-zuul-ratelimit</artifactId>
    <version>2.2.7.RELEASE</version>
</dependency>

<!-- 如果项目中有redis的话可以直接使用,我们应用中用到了redis所以直接以它为存储媒介 -->
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>

spring-cloud-zuul-ratelimit的最新版本是2.4.X,为什么这里用到是2.2.7。这是因为我们sc的版本比较低是1.5的,导致版本匹配不上,查阅了各个版本发现2.2.7比较兼容,如果大家应用的时候发现配置不生效,很有可能是版本不兼容导致的,我这边不兼容的原因是RateLimitProperties中有的注解使用版本过高,导致配置不生效,大家可以根据实际情况做调试查看。

yaml配置
zuul:
  ratelimit:
    key-prefix: your-prefix # 缓存key的名称定义前缀。
    enabled: true
    repository: REDIS
    behind-proxy: true
    add-response-headers: true
    default-policy-list: # 可选,默认的全局配置,如果根据规则查询不到配置则应用这个定义的配置
      - limit: 10 #可选,时间窗口内最多访问次数
        quota: 1000 # 可选时间窗口单位是秒
        refresh-interval: 60 # 默认的刷新时间窗口的间隔。
        type: # 可选 规则类型
          - user	
          - origin	# IP
          - url	
          - http_method # HTTP方法  可以组合
    policy-list:   # 具体的规则定义
      myServiceId:  # SpringCloud的服务编号
        - limit: 10 # optional - request number limit per refresh interval window
          quota: 1000 # optional - request time limit per refresh interval window (in seconds)
          refresh-interval: 60 #default value (in seconds)
          # 以下是参考的规则案例 URL是采用左侧前缀方式
          type: #optional
            - user
            - origin
            - url
        - type: #optional value for each type
            - user=anonymous
            - origin=somemachine.com
            - url=/api #url prefix
            - role=user
            - http_method=get #case insensitive
        - type:
            - url_pattern=/api/*/payment

这里需要说明的是:

  • limit : 1
  • quota : 10
  • refresh-interval : 60
    三个组合在一起的意思就是 : 在10秒内如果访问次数超过1次,则会被限流,一旦限流需要在60秒之后才会被解封

根据以上配置全局默认配置限流的功能已经OK了,特定的URL配置其实也是有的,但是需要每次在配置文件中定义,网关本身是所有流量的入口,如果每次配置都需要改配置文件然后再重启无疑是痛苦的。

我们如果阅读过相关的源码会发现,特定的URL是放在了RateLimitPropertiespolicyList集合中,然而这个集合是个Map对象,key是服务编号,value是特定的URL规则,可以是多个

我之前想做一个功能就是将所有服务的URL进行统一管理,然后业务同学根据接口的需求自己定义接口访问频率(注解),接口开发完成之后,需要限流的URL数据同步到Mysql表中,最终同步到Redis缓存里面,网关则根据缓存里面的频率规则直接应用。

不过目前功能没有实现完全,后续如果有需要的可以留言,完成了会贴代码。
这里提供一些实现思路:

  • 实现ApplicationRunner接口,在应用启动的时候回调run方法。
      1. 负责同步Mysql的路由数据到redis中
      1. 实现一个间隔刷新路由的线程

如果上文有什么不对的地方欢迎指正讨论,共同进步。

  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 3
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值