大家好,今天小编关注到一个比较有意思的话题,就是关于ratelimiter抢购秒杀的问题,于是小编就整理了1个相关介绍ratelimiter抢购秒杀的解答,让我们一起看看吧。
这种限制接口调用次数的方式,我们通常称之为限流,那么为什么要做限流呢,一般有两种原因:
1. 首先是防止服务提供方被大量的请求击垮
我们开发一个项目,最理想的状况是有多少请求,都可以正常地响应,但是在现在的互联网环境,我们很难评估用户的增长,很难评估访问量有多少,甚至有些时候会遇到恶意攻击;那么相比于项目被流量击垮,【限制流量,只满足部分访问的正常响应】要好一些。
简单说就是:满足所有请求 > 满足部分请求 > 项目被击垮,所有请求无法响应。
2. 计费
现在很多平台对外开发的接口,并不全是免费的,比如普通会员每天只能调用 1000 次接口,高级会员每天可以调用 10 万次接口,或者按照调用量计费。
那么如何限制服务接口的调用次数呢?
使用限流算法
通常我们可以通过限流算法达到限制接口调用次数,比如计数器法、滑动窗口法、漏桶算法、令牌桶算法,这里我们就用令牌桶算法举例。
令牌桶算法,我们可以看做有一个桶,桶里面有 N 个令牌,并且系统会以一个恒定的速度往桶里投放令牌,每次处理之前先要获取令牌,如果获取不到的话,就拒绝服务;在这里我们使用 Google 出品的 Guava 工具库,里面提供了一个开箱即用的令牌桶 RateLimiter。
如图,我们编写了一个简单的接口,省略了业务逻辑,只返回一个字符串;我们设置 RateLimiter.create(2),表示每秒不超过 2 个任务被提交。
让我们用接口工具模拟一下并发调用:
他强任他强,我自巍然不动。因为我们使用了限流算法,每秒只处理 2 个请求,所以从日志中我们可以看到这样的效果:每秒只有两条日志。
分布式架构下的限流
因为使用开源的组件,限流的实现看起来非常简单,但是这里也有一个比较大的问题,就是实例中是一个应用包,但在实际的项目中,我们通常会是用集群部署的方式,将我们的应用部署在多台机器上,那么这时候该如何限流呢?
每台服务器上的应用自己控制自己的响应数量?比如每天只能调 100 次,那部署 10 台的话,总量就变成了 1000 次了;
反推?因为每天总量只能调 100 次,部署 10 台,那就是每台每天只能调 10 次?这是个很差的办法,先不说流量一定可以平均分配到每台机器上,如果有一台机器挂掉了,是不是今天只能支持调用 90 次了?
通常的解决方案,可以把令牌桶中的令牌,不要放在本地,而是放在一个公共的地方,比如 Redis 中,每次请求过来,就计算是否超过限制的总量,如果未超过,则正常处理,如果已超过,则返回错误信息。
具体做法是,用 Redis 中的 key-100 作为令牌桶,其中 100 表示一分钟可以调用 100 次,每次处理前对 value 进行减 1,返回的值大于 0 表示可以处理;每分钟将 value 设置回 100;或计数累加,开始是 0 ,不断累加,最后超过单位时间的总量限制;
不过这个方法要有一个定时任务,去设置令牌的数量,另外这种方法是不能应对突发流量的,比如前 59 秒一次请求也没有,第 60 秒来了 100 次,第 61 秒进入了一个新的周期,又来了 100 次请求 ,这样实际上是在两秒内处理了 200 次请求。
另外一种方案是使用 Redis 中的有序队列 Sorted Set ,存储近 100 次的调用时间,每次有新请求的时候,对比队列中第一个元素的时间和当前时间,如果相差超过 1 分钟,表示还没有超过流量限制,进行处理,并将第一个元素压出队列,将新的请求时间压入队列。
我将持续分享Java开发、架构设计、程序员职业发展等方面的见解,希望能得到你的关注。
任何一个大型项目,在发展到一定时期后由于其内部逻辑及功能模块的增多,就需要将业务及模块解耦进行模块化开发,每个模块折分成多个颗粒度较小的独立服务,这就是“微服务”。但是随着服务的折分,系统间的调用关系错综复杂,也会出现一些问题(比如出错了不好定位等),所以伴随微服务的还有服务治理,服务治里主要包括:鉴权、限流(也就是我们说的限制接口调用次数)、降级、熔断、监控等。
为什么要对接口做限流?
我们知道,不管是系统还是API,都是有性能瓶颈的。对于微服务来说,我们的API会被很多业务去调用,一旦某个API的调用次数过于频繁(请求流量超过了预期),可能会导致此API响应变得缓慢,严重时会Down掉,进而会影响相关联的API及整个服务的稳定。
所以说限流的目的就是通过对并发/请求进行限速(可以理解为生活中的保险丝),一旦达到限制速率后要么拒绝服务、要么排队等待或降级处理,以此保证系统稳定性。
限流算法有哪些?
这里说的限流算法其实就是限流的机制策略,业内常用的有:令牌桶算法、漏桶算法、Redis计数器等。
其中Redis计数器这种实现方法是我们推荐的,因为Redis本身是一款内存型K/V数据库,能便捷设置Key的过期时间(TTL),而且速度效率都很高,最重要的是易于分布式布署。
基于Redis计数器实现限流
大概原理是:
1、对于每个API地址进行MD5,此MD5值代表的就是此API地址,然后作为Redis的Key,并且设置好TTL;
2、每次API请求后,给此Key的值递增1;
3、在Key有效期内,若最终值超过某个数,后续的请求则进行拒绝、等待处理。
目前微服务领域,Spring Cloud全家桶能提供完整的解决方案,有兴趣的朋友可以了解下。
以上就是我的观点,对于这个问题大家是怎么看待的呢?欢迎在下方评论区交流 ~ 我是科技领域创作者,十年互联网从业经验,欢迎关注我了解更多科技知识!
到此,以上就是小编对于ratelimiter抢购秒杀的问题就介绍到这了,希望介绍关于ratelimiter抢购秒杀的1点解答对大家有用。