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

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

时间:2024-01-12 10:33:22浏览次数:28  
标签:掌控 窗口 流量 并发 限流 支付 退款 分布式

这是《百图解码支付系统设计与实现》专栏系列文章中的第(10)篇。点击上方关注,深入了解支付系统的方方面面。

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

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

1. 前言

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

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

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

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

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

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

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

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

2. 几种方案对比

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

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

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

3. 固定窗口

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

固定窗口算法的好处是简单,缺点也很明显,就是无法应对突发流量,比如每秒30并发,如果前100ms来了30个请求,那么在10ms内就会把30个请求打出去,后面的900ms的请求全部拒绝。

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

工作流程:

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

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

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

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


<未完待续>


标签:掌控,窗口,流量,并发,限流,支付,退款,分布式
From: https://blog.51cto.com/u_16485618/9211343

相关文章

  • 深度解析Java中的ReadWriteLock:高效处理并发读写操作
    第1章:引言大家好,我是小黑,今天咱们聊聊读写锁。当多个线程同时对同一数据进行读写操作时,如果没有合理的管理,那数据就乱套了。就好比小黑在写日记,突然来了一帮朋友,大家都想往日记本上写点什么,不加以控制,日记本就成了涂鸦板。这时,ReadWriteLock就派上用场了。它可以确保当一个线程......
  • springcloud分布式微服务
                      ......
  • 优雅处理并发:Java CompletableFuture最佳实践
    第1章:引言大家好,我是小黑,今天,小黑要和大家聊聊CompletableFuture,这个Java8引入的强大工具。在Java传统的Future模式里,咱们都知道,一旦开始了一个异步操作,就只能等它结束,无法知道执行情况,也不能手动完成或者取消。而CompletableFuture呢,就像它的名字一样,是可以"完全控制"的Futur......
  • 高并发扣款,如何保证结果一致性
    转载至我的博客,公众号:架构成长指南在金融系统中,我们会跟钱打交道,而保证在高并发下场景下,对账户余额操作的一致性,是非常重要的,如果代码写的时候没考虑并发一致性,就会导致资损,本人在金融行业干了8年多,对这块稍微有点经验,所以这篇聊一下,如何在并发场景下,保证账户余额的一致性1......
  • 分布式机器学习的故事:Docker改变世界
    分布式机器学习的故事:Docker改变世界Docker最近很火。Docker实现了“集装箱”——一种介于“软件包”和“虚拟机”之间的概念——并被寄予厚望,以期革新Internet服务以及其他大数据处理系统的开发、测试、和部署流程。为了使用Docker,需要了解不少工具及其设计思路;而这些工具的文......
  • 中间件 ZK分布式专题与Dubbo微服务入门 4-8 权限acl详解,acl的构成-scheme与id
    0课程地址https://coding.imooc.com/lesson/201.html#mid=12704 1重点关注1.1权限的构成权限字符串缩写crdwaCREATE:创建子节点READ:获取节点/子节点WRITE:设置节点数据 DELETE:删除子节点ADMIN:设置权限  2课程内容  ......
  • 中间件 ZK分布式专题与Dubbo微服务入门 4-9 acl的构成-permissions
    0课程地址https://coding.imooc.com/lesson/201.html#mid=12705 1重点关注1.1权限的构成权限字符串缩写crdwaCREATE:创建子节点READ:获取节点/子节点WRITE:设置节点数据 DELETE:删除子节点ADMIN:设置权限  2课程内容  ......
  • Go语言接口防并发常用方案
    Go语言接口防并发常用方案原创 枫潇潇兮 程序员技术成长之路 2024-01-0908:30 发表于福建 听全文Go语言中处理并发的常见策略涉及了并发原语,如互斥锁(sync.Mutex)、读写锁(sync.RWMutex)、通道(channel)以及原子操作(sync/atomic)。接口(Interface)本身并不直接参与并发控制,但......
  • 探索服务网格与 OpenTelemetry 的协同之分布式跟踪
    背景分布式跟踪分布式跟踪是监控和诊断微服务请求流程的关键技术,也是可观测性的关键组成部分,提供了对微服务架构中复杂交互和性能问题的深入洞察。它通过提供服务间请求链路的清晰视图来管理复杂性,并帮助识别性能瓶颈、优化资源分配、快速定位和解决故障,提高系统的整体可靠性。服务......
  • Go 语言为什么不支持并发读写 map?
    大家好,我是frank,「Golang语言开发栈」公众号作者。01介绍在Go语言项目开发中,我们经常会使用哈希表map,它的时间复杂度是O(1),Go语言中的map使用开放寻址法避免哈希碰撞。Go语言中的map并非原子操作,不支持并发读写操作。Go官方认为map在大多数情况下是使用map进行并......