当您API有大量消费者或者请求量猛增到影响程序可用性的时候,您可能需要对API进行速率限制。所以对API进行限速的在于:在增加可靠性和可用性的同时来保护基础架构,你不希望某个恶意的API消费者或者差劲的API客户端开发者通过Dos攻击把你的应用搞垮;保护你的产品,你同样不希望你的产品被滥用,例如大规模用户注册或创建很多垃圾内容。

什么是限速

限速(Rate-Limiting)系统可以控制网络接口发送和接受流量的速率。对于Web API来说,限速系统被用来控制一段时间内某个程序或客户端允许调用某个API的次数,超过该次数的流量会被拒绝。例如Github的API只允许开发者每小时发送5000次请求。




接口请求nginx ERR_EMPTY_RESPONSE 接口请求已达上限_webapi 超过了最大请求长度


限速

策略

在对API限速之前,您首先要考虑好限速的策略,通常一个好的限速策略有以下这两个特性:

  • 易于理解,易于解释,易于使用
  • 针对特殊情况,对开发者可以不限速

限速策略需考虑这些

限速策略还需要考虑这些问题

  1. 颗粒速率限制还是全局速率限制
  2. 针对比较简单的系统,很多开发者采用的是全局速率限制,但是如果某个API消费了大量的资源,你可能需要为每个API单独进行速率限制。所以颗粒的速率限制会保护你的基础架构不被任何耗资巨大的API节点所引起的无理流量尖峰造成严重影响。
  3. 测量每个用户、应用、客户端
  4. 你想要进行速率限制的资源还依赖于您的API的身份认证方式。需要用户身份认证的API通常可以按照用户进行速率限制,而需要应用身份认证的API通常是基于每个应用来进行速率限制。对于未认证的API,我能想到的就是按照IP地址进行速率限制。
  5. 是否支持突发流量
  6. 有些API,尤其是企业内部的系统,需要支持超过速率限制的突发流量。这种情况下,可以采用令牌桶算法(Token Bucket)来实现速率限制。
  7. 是否允许例外
  8. 有时候,对于应用的开发者来说,一个限速策略或一组限速策略可能都不太适用。对于你信任的开发者,如果他们的请求超出了配额,可能需要给他们一些例外的允许,但是在此之前,你要做这些工作:
  9. 保证每个开发者的用例对客户来说都是合理有益的。
  10. 要确认确实没有其它不超出约束的办法来达到相同的目的。
  11. 确保你的基础架构确实可以支撑想要请求的速率。

针对 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速率限制的几种算法。