我在业余时间开发了一款自己的独立产品:升讯威在线客服与营销系统。陆陆续续开发了几年,从一开始的偶有用户尝试,到如今线上环境和私有化部署均有了越来越多的稳定用户。
而我收到的用户需求也越来越多,产品化的需求,个性化的需求都有。最近两天收到一个用户的开放接口需求,为客服系统的 Open Api 开放接口提供一个获取在线访客列表的接口。
如何在 .NET 系统中实现 Open Api 我在前文分解过,今天我想分享的是如何为在线客服系统的开放接口设计实现一个 QPS 限流功能。
如下图所示,在为用户提供接口的过程中,我对这个接口应用了基本的 QPS 限流技术。
什么是 QPS 接口限流
QPS(Queries Per Second,查询每秒)接口限流是指对 API 或网络服务的访问进行限制,控制每秒钟可以接受的最大请求数量。这种限流机制常用于防止服务器因为过多的请求而被过载,从而保证服务的稳定性和性能。
QPS 限流的具体做法通常是:
-
设置最大 QPS 限制:对于每个用户、IP 地址或系统等,设定一个请求次数上限。比如,一个接口每秒钟最多允许 100 次请求。
-
超限处理:当请求数超过设定的 QPS 限制时,系统通常会拒绝多余的请求,返回错误信息(如 HTTP 429 Too Many Requests)。有时,也可能选择进行排队、重试等处理。
-
分级限流:为了避免单一用户或 IP 造成整个系统的拥塞,可以根据用户类型、接口的优先级等进行不同的限流策略。
-
突发流量处理:对于突发的高频请求,系统可能允许短时间内的超出限制的请求,但会有相应的窗口期或滑动窗口来平滑流量。
QPS 限流的目的通常是:
- 防止恶意请求或过多请求导致服务崩溃。
- 确保公平性,避免单个用户或请求占用过多资源。
- 提高服务的可用性和稳定性。
.NET 接口有哪些QPS限流方案
1. 基于内存的限流(Memory-based Rate Limiting)
- 这种方法使用内存中的数据结构(如
Dictionary
或Queue
)来记录每个用户或请求的时间戳,从而计算每秒钟的请求数量。 - 适用于流量较小、对性能要求较高的场景。
示例:
public class MemoryRateLimiter
{
private readonly int _maxQps;
private readonly Dictionary<string, Queue<DateTime>> _requests = new Dictionary<string, Queue<DateTime>>();
public MemoryRateLimiter(int maxQps)
{
_maxQps = maxQps;
}
public bool IsRequestAllowed(string key)
{
var now = DateTime.UtcNow;
if (!_requests.ContainsKey(key))
{
_requests[key] = new Queue<DateTime>();
}
var requestQueue = _requests[key];
// Remove requests older than 1 second
while (requestQueue.Count > 0 && (now - requestQueue.Peek()).TotalSeconds >= 1)
{
requestQueue.Dequeue(