精确掌控并发:分布式环境下并发流量控制的设计与实现(一)

这是《百图解码支付系统设计与实现》专栏系列文章中的第(10)篇。

本篇主要讲清楚常用的并发流量控制方案,包括固定窗口、滑动窗口、漏桶、令牌桶、分布式消息中间件等,以及各种方案在支付系统不同场景下的应用。

在非支付场景,也常常需要用到这些并发流量控制方案。

1. 前言

在互联网应用里面,并发流量控制无所不在。在支付系统中,流量控制同样是一个关键的技术方面,主要用于确保系统的稳定性和可靠性,尤其在高流量的情况下。以下是一些主要使用流量控制的场景:

  1. 对外API限流:对外提供的API(如支付接口)需要限流来保护后端服务不会过载。
  2. 保护外部渠道:大促时,对下流渠道的支付流量要做削峰填谷,避免突发流量把渠道打挂。
  3. 保护内部应用:大促时,内部各应用要根据流量模型配置限流值,避免形成雪崩。
  4. 满足外部退款限流要求:电商批量提交退款时,支付系统内部要在分布式集群环境下对某个渠道实现低至1TPS的退款并发,避免超过渠道退款并发导致大批量失败。

特别说明的是,流量控制通常包括限流和限速

我们通常说的限流 ,就是流量达到一定程度,超过的流量会全部立即拒绝掉,也就是快速失败。比如上面的API限流。

限速 一般是指接收流量后,先保存到队列中,然后按指定的速度发出去如果超过队列最大值,才会拒绝。比如上面的支付流量和退款流量打到外部渠道。

另外,支付和退款流量控制虽然都是流量控制,但有一些细小的区别:

  1. 支付的限流TPS通常比较高 ,从十几TPS到几百TPS都有,排队时效性要求很高,秒级内就要付出去。
  2. 退款的限流TPS通常比较低 ,在国外的基础设施建设很差,甚至部分渠道要求退款1TPS。但是排队时效性要求很低,几天内退出去就行。

2. 几种方案对比

**固定窗口:**算法简单,对突然流量响应不够灵活。超过流量的会直接拒绝,通常用于限流。

滑动窗口: 算法简单,对突然流量响应比固定窗口灵活。超过流量的会直接拒绝,通常用于限流。

漏桶算法: 在固定窗口的基础之上,使用队列缓冲流量。提供了稳定的流量输出,适用于对流量平滑性有严格要求的场景。后面会介绍如何应用到外部渠道退款场景。
令牌桶算法: 在滑动窗口的基础之上,使用队列缓冲流量。能够允许一定程度的突发性流量,但实现较为复杂。
**分布式消息中间件:**如Kafka和RabbitMQ等,能够有效地对消息进行缓冲和管理,增加系统复杂性,且如果需要精确控制流量还需要引入额外的机制。后面会介绍如何应用到外部渠道支付场景。

3. 固定窗口

固定窗口算法,也称为时间窗口算法,是一种流量控制和速率限制策略。此算法将时间轴分割成等长、不重叠的时间段,称为"窗口"。每个窗口都有一个独立的计数器,用于跟踪窗口期间的事件数量(如API调用、数据包传输等)。

工作流程:

  1. 窗口定义:首先确定窗口大小,比如1秒钟。
  2. 计数:每当发生一个事件(比如一个请求到达),就在当前窗口的计数器上加一。
  3. 限制检查:如果当前窗口的计数器达到预设阀值,则拒绝新的请求。直到下一个窗口开始。
  4. 窗口重置:当前窗口结束时,计算数器重置为零,开始下一个窗口计数。

可以使用redis实现,比如以时间戳为key,value代表请求数,过期时间为窗口期+5秒(主要是兼容各服务器的时间差)。

需要注意的:下面的设置和加1操作,需要使用lua脚本,保证原子性。

<未完待续>

相关推荐
工业甲酰苯胺1 小时前
分布式系统架构:服务容错
数据库·架构
Data跳动1 小时前
Spark内存都消耗在哪里了?
大数据·分布式·spark
超爱吃士力架1 小时前
邀请逻辑
java·linux·后端
Java程序之猿2 小时前
微服务分布式(一、项目初始化)
分布式·微服务·架构
来一杯龙舌兰3 小时前
【RabbitMQ】RabbitMQ保证消息不丢失的N种策略的思想总结
分布式·rabbitmq·ruby·持久化·ack·消息确认
AskHarries3 小时前
Spring Cloud OpenFeign快速入门demo
spring boot·后端
isolusion4 小时前
Springboot的创建方式
java·spring boot·后端
zjw_rp4 小时前
Spring-AOP
java·后端·spring·spring-aop
节点。csn5 小时前
Hadoop yarn安装
大数据·hadoop·分布式