当您API有大量消费者或者请求量猛增到影响程序可用性的时候,您可能需要对API进行速率限制。所以对API进行限速的在于:在增加可靠性和可用性的同时来保护基础架构,你不希望某个恶意的API消费者或者差劲的API客户端开发者通过Dos攻击把你的应用搞垮;保护你的产品,你同样不希望你的产品被滥用,例如大规模用户注册或创建很多垃圾内容。
什么是限速
限速(Rate-Limiting)系统可以控制网络接口发送和接受流量的速率。对于Web API来说,限速系统被用来控制一段时间内某个程序或客户端允许调用某个API的次数,超过该次数的流量会被拒绝。例如Github的API只允许开发者每小时发送5000次请求。
限速
策略
在对API限速之前,您首先要考虑好限速的策略,通常一个好的限速策略有以下这两个特性:
- 易于理解,易于解释,易于使用
- 针对特殊情况,对开发者可以不限速
限速策略需考虑这些
限速策略还需要考虑这些问题:
- 颗粒速率限制还是全局速率限制
- 针对比较简单的系统,很多开发者采用的是全局速率限制,但是如果某个API消费了大量的资源,你可能需要为每个API单独进行速率限制。所以颗粒的速率限制会保护你的基础架构不被任何耗资巨大的API节点所引起的无理流量尖峰造成严重影响。
- 测量每个用户、应用、客户端
- 你想要进行速率限制的资源还依赖于您的API的身份认证方式。需要用户身份认证的API通常可以按照用户进行速率限制,而需要应用身份认证的API通常是基于每个应用来进行速率限制。对于未认证的API,我能想到的就是按照IP地址进行速率限制。
- 是否支持突发流量
- 有些API,尤其是企业内部的系统,需要支持超过速率限制的突发流量。这种情况下,可以采用令牌桶算法(Token Bucket)来实现速率限制。
- 是否允许例外
- 有时候,对于应用的开发者来说,一个限速策略或一组限速策略可能都不太适用。对于你信任的开发者,如果他们的请求超出了配额,可能需要给他们一些例外的允许,但是在此之前,你要做这些工作:
- 保证每个开发者的用例对客户来说都是合理有益的。
- 要确认确实没有其它不超出约束的办法来达到相同的目的。
- 确保你的基础架构确实可以支撑想要请求的速率。
针对 ASP.NET Core Web API
针对ASP.NET Core Web API项目,如果不采用网关的话,我使用的是:
AspNetCoreRateLimit。
Github的地址是:
https://github.com/stefanprodan/AspNetCoreRateLimit。
这个我会在后续文章中介绍。
针对API网关
.NET Core的Ocelot网关内置速率限制功能。
https://ocelot.readthedocs.io/en/latest/features/ratelimiting.html
而其它正经的API网关也都有该功能,例如Kong等。Kong的官网有一篇介绍API速率限制算法的文章,讲的很好可以看看:
https://konghq.com/blog/how-to-design-a-scalable-rate-limiting-algorithm/
我也会在下一篇文章中介绍API速率限制的几种算法。