API限流方案调研

对于高并发的系统,有三大利器来保证系统的稳定可用:缓存、降级、限流

缓存即是提升系统访问速度和增大系统能处理的容量,可谓是抗高并发流量的银弹

降级即是把服务暂时屏蔽,直接越过,待高峰后再恢复

限流即流量限制,限流的目的是在遇到流量高峰期或者流量突增(流量尖刺)时,把流量速率限制在系统所能接受的合理范围之内,不至于让系统被高流量击垮

(熔断即是把服务直接短路掉,返回一个mock的值)

目前有几种常见的限流方式:

  1. 通过限制单位时间段内调用量来限流
  2. 基于redis的限速器来限流(分布式系统)
  3. 使用漏桶(Leaky Bucket)算法来进行限流
  4. 使用令牌桶(Token Bucket)算法来进行限流(Guava实现,RateLimiter)

具体分析:

第1种方案:

       通过一个计数器统计单位时间段某个服务的访问量,如果超过了我们设定的阈值,则该单位时间段内则不允许继续访问、或者把接下来的请求放入队列中等待到下一个单位时间段继续访问。

这种方案的核心在于阈值的设置,缺点是需要依赖监控系统来分析调用量,可能存在“突刺消耗”,即单位时间段的前几秒内流量达到阈值,导致该时间段内剩余的时间内该服务“拒绝服务”,高并发下仍然可能压垮系统

第2种方案:

       基于RedisAPI中的INCR,实现限速器,它将 API 的最大请求数限制在每个 IP 地址每秒钟多少个之内: 其中要考虑INCR命令和EXPIRE(过期时间)命令的原子性,最终解决是使用Lua脚本(Lua脚本是Redis2.6及以上才支持)

第3种方案:

      漏桶算法是常用算法之一,不管遇到多大的流量,都以固定速率流出,超出部分直接丢弃,缺点显而易见:不能应对突发性流量,直接导致服务到达瓶颈,

第4种方案:

      令牌桶算法是漏桶算法的改进,随着时间流逝,系统会按恒定1/QPS时间间隔(如果QPS=100,则间隔是10ms)往桶里加入Token,如果桶已经满了就不再加了.新请求来临时,会各自拿走一个Token,

如果没有Token可拿了就阻塞或者拒绝服务,它能应对突发的流量,可以改变放入桶中的令牌的速率。

(令牌桶的具体实现:Google开源工具包Guava提供了限流工具类RateLimiter,实现类似于java中的信号量Semaphore,它支持两种方式:一种是如果拿不到立刻返回false,一种会阻塞等待一段时间看能不能拿到。)

 

以上4种实现方式都是需要自行编码实现,在SpringCloud的组件中Spring Cloud Zuul RateLimiter对Guava的RateLimiter进行了封装,需要引入springCloud,完全基于配置来实现限流,并且提供了4种粒度的限流类型:

URL

针对URL/接口进行限流

Service

针对服务进行限流,如果没有配置限流类型,则此类型生效

Request Origin

针对请求的Origin进行限流

Authenticated User

针对请求的用户进行限流

 

结论:

经过讨论,

1,组件选型:先采用“令牌桶算法”的方案,如果后续需要引入“Spring Cloud Zuul”组件,此部分功能可直接由网关组件接管。

2,过流保护策略:当达到上限时,方案1:直接丢弃;方案2:等待。   出于高并发考虑,先选择直接丢弃方案。

 

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值