Guava工具类 微服务如何限制接口调用次数?
微服务如何限制接口调用次数?
这种限制接口调用次数的通常被称为限流,那么为什么要限制流量呢?一般有两个原因:
1.首先是防止服务提供者被大量的请求淹没。
我们在开发一个项目的时候,理想的情况是可以正常响应很多请求,但是在现在的互联网环境下,我们很难评估用户的增长,访问的数量,甚至有时候会遇到恶意攻击;那么,与其项目被流量碾压,不如限制流量,只满足部分接入的正常响应。
简单来说:满足所有请求,满足部分请求,项目被碾压,所有请求都无法响应。
充电
目前很多平台开发的接口并不都是免费的。比如普通会员一天只能调用接口1000次,高级会员一天可以调用接口10万次,或者按调用量收费。
那么如何限制服务接口调用的次数呢?
使用电流限制算法
通常我们可以通过限流算法来限制接口调用的次数,比如计数器法、滑动窗口法、漏桶、令牌桶算法,这里我们以令牌桶算法为例。
令牌桶算法,我们可以把它想象成一个桶,里面有n个令牌,系统会匀速把令牌放进桶里。在每次处理之前,我们必须首先获得令牌。如果我们能 如果得不到,我们将拒绝服务。这里我们使用Google生产的Guava工具库,它提供了一个开箱即用的令牌桶速率限制器。
如图,我们写了一个简单的接口,省略了业务逻辑,只返回一个字符串;我们设置(2),这意味着每秒提交的任务不超过2个。
让 使用接口工具模拟并发调用:
他逼他坚强,我却立场坚定。因为我们使用限流算法,并且每秒只处理2个请求,所以我们可以从日志中看到每秒只有2个日志的效果。
分布式架构下的电流限制
由于使用了开源组件,限流的实现看起来很简单,但是这里也有一个很大的问题,就是实例是一个应用包,但是在实际项目中,我们通常是通过集群部署的将我们的应用部署在多台机器上,那么这个时候如何限流呢?
每台服务器上的应用程序控制自己的响应数量?比如一天只能调100次,如果调配10台,总数就变成1000次;
反推?因为总量一天只能调100次,调配10个单位,也就是每个单位一天只能调10次?这是一个非常糟糕的方法。更不用说流量可以平均分配到每台机器。如果一机挂机,今天只能支持90个吗?
通常的解决方案是在公共场所(如热地)将令牌放入令牌桶,而不是在本地。在S中,每次请求到来时,都会计算是否超过限制的总量。如果没有超过,则正常处理,如果超过,则返回错误消息。
具体来说,Redis中的key-100作为令牌桶,100表示一分钟可以调用100次,每次处理前将值减1,返回值大于0,表示可以处理;每分钟将数值设回100;或者计数累加,从0开始,不断累加,最后超过单位时间的总量限制;
但是,这个方法应该有一个定时任务来设置令牌的数量。此外,这种方法可以 t应对突发流量,比如前59秒没有请求,第60秒来了100个请求,第61秒来了100个请求,实际上两秒处理了200个请求。
另一种方案是使用Redis中的有序队列排序集来存储近100次的调用时间。每次有新请求时,将队列中第一个元素的时间与当前时间进行比较。如果相差超过1分钟,说明没有超过流量限制,然后进行处理,把第一个元素推出队列,把新的请求时间推入队列。
我会继续分享我对Java开发、架构设计、程序员职业发展等方面的看法,希望得到大家的关注。
版权声明:本文内容由互联网用户自发贡献,本站不承担相关法律责任.如有侵权/违法内容,本站将立刻删除。