这是《百图解码支付系统设计与实现》专栏系列文章中的第(10)篇。
本篇主要讲清楚常用的并发流量控制方案,包括固定窗口、滑动窗口、漏桶、令牌桶、分布式消息中间件等,以及各种方案在支付系统不同场景下的应用。
在非支付场景,也常常需要用到这些并发流量控制方案。
在互联网应用里面,并发流量控制无所不在。在支付系统中,流量控制同样是一个关键的技术方面,主要用于确保系统的稳定性和可靠性,尤其在高流量的情况下。以下是一些主要使用流量控制的场景:
特别说明的是,流量控制通常包括限流和限速。
我们通常说的限流,就是流量达到一定程度,超过的流量会全部立即拒绝掉,也就是快速失败。比如上面的API限流。
限速一般是指接收流量后,先保存到队列中,然后按指定的速度发出去,如果超过队列最大值,才会拒绝。比如上面的支付流量和退款流量打到外部渠道。
另外,支付和退款流量控制虽然都是流量控制,但有一些细小的区别:
固定窗口:算法简单,对突然流量响应不够灵活。超过流量的会直接拒绝,通常用于限流。
滑动窗口: 算法简单,对突然流量响应比固定窗口灵活。超过流量的会直接拒绝,通常用于限流。
漏桶算法:在固定窗口的基础之上,使用队列缓冲流量。提供了稳定的流量输出,适用于对流量平滑性有严格要求的场景。后面会介绍如何应用到外部渠道退款场景。
令牌桶算法:在滑动窗口的基础之上,使用队列缓冲流量。能够允许一定程度的突发性流量,但实现较为复杂。
分布式消息中间件:如Kafka和RabbitMQ等,能够有效地对消息进行缓冲和管理,增加系统复杂性,且如果需要精确控制流量还需要引入额外的机制。后面会介绍如何应用到外部渠道支付场景。
固定窗口算法,也称为时间窗口算法,是一种流量控制和速率限制策略。此算法将时间轴分割成等长、不重叠的时间段,称为“窗口”。每个窗口都有一个独立的计数器,用于跟踪窗口期间的事件数量(如API调用、数据包传输等)。
工作流程:
可以使用redis实现,比如以时间戳为key,value代表请求数,过期时间为窗口期+5秒(主要是兼容各服务器的时间差)。
需要注意的:下面的设置和加1操作,需要使用lua脚本,保证原子性。
<未完待续>