限流的解决方案

个人比较喜欢和赞同的限流方案是:单机下使用RateLimiter,分布式下限流采用redis+lua

1. 高并发三板斧

我们常说的大流量,名词:TPS(每秒事务量),QPS(每秒请求量),应对大流量的三种方式是(也是高并发的三板斧):

  • 缓存:让数据尽早进入缓存,离程序近一点,不要大量频繁的访问DB。
  • 降级:访问一些网站的时候,会出现让你稍后访问的情况,如果不是核心链路,那么就把这个服务降级掉。比如说,一些软件,拿到数据后,做个性化排序展示,如果在大流量下,对于vip用户可以通过,对于普通用户做降级,这个排序就可以降级掉
  • 限流:限流就是保证在一定时间内服务能够处理的请求数量,防止大流量出现,不至于让系统崩溃,导致所有请求都处理不了了,想在一定时间内把请求限制在一定范围内,保证系统不被冲垮,同时尽可能提升系统的吞吐量。

2. 限流的常用算法

限流的常用处理手段有:计数器、漏桶、令牌

  • 计数器:一种比较简单的限流算法,用途比较广泛。在一段时间内,进行计数,与阀值进行比较,到了时间点,将计数器清0。(缺陷:在整个时间段没有流量,但是在时间临界点突然出现很多请求,例如1分钟限流100,在0秒到58秒没有请求,59秒出现100哥请求,1分钟的时候又出现100哥请求,短时间内大量请求,系统可能还是会崩溃)

  • 漏桶:计数器存在临界点缺陷,漏桶算法可以用来解决这个问题。有一个固定的桶,进水的速率是不确定的,但是出水的速率是恒定的,当水满的时候会溢出的:
    限流的解决方案_第1张图片

  • 令牌桶:漏桶的出水速度是恒定的,那么意味着如果瞬时大流量的话,将有大部分请求被丢弃掉(也就是所谓的溢出)。为了解决这个问题,令牌桶进行了算法改进。
    生成令牌的速度是恒定的,而请求去拿令牌是没有速度限制的。这意味,面对瞬时大流量,该算法可以在短时间内请求拿到大量令牌[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

限流的解决方案_第2张图片

不管是令牌桶拿不到令牌被拒绝,还是漏桶的水满了溢出,都是为了保证大部分流量的正常使用,而牺牲掉了少部分流量,这是合理的,如果因为极少部分流量需要保证的话,那么就可能导致系统达到极限而挂掉,得不偿失。这就是限流的原则。

3. 限流工具

  • 单机限流工具:Guava RateLimiter
    客户中心接口或者是执行sql限流都用到了这个限流方式:
    RateLimiter基于令牌桶算法,我们只需要告诉RateLimiter系统限制的QPS是多少,那么RateLimiter将以这个速度往桶里面放入令牌,然后请求的时候,通过tryAcquire()方法向RateLimiter获取令牌就行了。
  • 分布式场景下的限流
    上面所说的三种限流的算法,都是针对单机而言的,大部分的场景,单机的限流已经足够了。分布式下限流的手段常常需要多种技术相结合,比如Nginx+LuaRedis+Lua等去做。客户中心的select_scroll限流采用redis+lua

(个人见解:所有和分布式有关的问题,解决方案中都有一种redis有关的解决方案,redis应用广泛,刚好是单线程,解决了分布式下的并发问题,而且还速度快,是一种很好的选择)

你可能感兴趣的:(学习,JAVA)