Rate limiting
RateLimiter 从概念上来讲,速率限制器会在可配置的速率下分配许可证。
从最终用户访问安全的角度看,设想有人想暴力碰撞网站的用户密码;或者有人攻击某个很耗费资源的接口;或者有人想从某个接口大量抓取数据。大部分 人都知道应该增加 Rate limiting,做请求频率限制。从安全角度,这个可能也是大部分能想到,但不一定去做的薄弱环节。
从整个架构的稳定性角度看,一般 SOA 架构的每个接口的有限资源的情况下,所能提供的单位时间服务能力是有限的。假如超过服务能力,一般会造成整个接口服务停顿,或者应用 Crash,或者带来连锁反应,将延迟传递给服务调用方造成整个系统的服务能力丧失。有必要在服务能力超限的情况下 Fail Fast。
另外,根据排队论,由于 API 接口服务具有延迟随着请求量提升迅速提升的特点,为了保证 SLA 的低延迟,需要控制单位时间的请求量。这也是 Little’s law 所说的。
所以,提供资源能够支撑的服务,将过载请求快速抛弃对整个系统架构的稳定性非常重要。这就要求在应用层实现 Rate limiting 限制。
Proxy 层的实现,针对部分 URL 或者 API 接口进行访问频率限制
Nginx 模块
limit_req_zone $binary_remote_addr zone=one:10m rate=1r/s;server { location /search/ { limit_req zone=one burst=5; }
Java应用层实现
Google Guava 提供了一个 RateLimiter 实现
/** * Created by haoting.wang on 2017/3/13. */public class RateLimiterDemo { //每秒处理一个 static RateLimiter rateLimiter = RateLimiter.create(1); private static int count = 10; static class Work implements Runnable{ int name; Work(int name){ this.name = name; } public void run() { rateLimiter.acquire(); System.out.println(name+"正在工作"); } } public static void main(String[] args){ for(int i = 0; i
但是更好的限制方式是池, 线程池、数据库连接池来限制访问数量,将过载的请求放在队列中,等待线程资源
这坑比啊 segmentfault,连个限流的标签都没,建个标签还要声望。mdzz