统一流控服务开源-1:场景&业界做法&算法篇
最近团队在搞流量安全控制,为了应对不断增大的流量安全风险。Waf防护能做一下接入端的拦截,但是实际流量会打到整个分布式系统的每一环:Nginx、API网关、RPC服务、MQ消息应用中心、数据库。瞬间的大流量对系统的整体的冲击还是很大的,一些连锁反应时刻刺激着我们的神经!所以,我们要设计开发我们自己的流控中心。解决我们的系统痛点问题。
一、首先,我们从系统需求说起:
1. 接入点IOT设备,瞬间批量上线&离线:几十万设备同时离线、上线后,带来的三遥数据、状态数据,瞬间打到后端。虽然有MQ扛了一层,但是MQ消费端是并发处理的,后端业务扛不住了
2. 大型促销发券活动,几十万用户瞬间异步发出上百万张优惠券。
3. API网关,时候接受第三方合作伙伴的定时访问,请求密集、数据访问大,后端RPC服务疲于应对。
4. DB层,上述场景最后60%的请求会落到DB端,磁盘、CPU压力大
5. Redis,大范围访问Redis中的缓存数据,TPS瞬间就上去了。
通过分析以上这些问题,都是由于瞬间流量过大造成,因此必须对大流量进行控制。流量控制越靠近链路开端,带来的效果越明显。
二、在设计流控之前,我们要看一下互联网业绩怎么做的!
我们借鉴了阿里的做法,毕竟作为云厂商和双11缔造者,流控方面的经验还是经过实际业务验证的!
总结一下:
- 流控说白了就是控制速率,在系统各个层面防止被大流量打爆
- 在系统的各个层面,流控策略和方式是不同的,API网关的、RPC服务的、MQ的
- 流量控制的维度可以是全局的、进程的、请求来源、用户及自定义维度
- 流量控制是动态的,应该根据系统的“并发特点”动态调配、控制
- 流控的根本目的就是保证系统的高可用性。
总结梳理了业界流量控制的做法之后,我们再看一下具体的流控算法及实现!
三、流控算法及实现
目前业界的流控算法的就这么几种:漏桶、令牌桶、计数器,我们一一展开介绍一下。
1. 漏桶(Leaky Bucket)算法
水(请求)先进入到漏桶里,漏桶以一定的速度出水(接口有响应速率),
当水流入速度过大会直接溢出(访问频率超过接口响应速率), 然后就拒绝请求,
可以看出漏桶算法能强行限制数据的传输速率.
有两个变量:
- 一个是桶的大小,支持流量突发增多时可以存多少的水(burst),
- 另一个是水桶漏洞的大小(rate)。
漏桶算法的问题:
- 水满了直接不让进、丢弃
- 桶容量问题
- 漏出速度控制问题
2. 令牌桶算法(Token Bucket)
随着时间流逝,系统会按恒定1/QPS时间间隔(如果QPS=100,则间隔是10ms)
往桶里加入Token(想象和漏洞漏水相反,有个水龙头在不断的加水),
如果桶已经满了就不再加了. 新请求来临时,
会各自拿走一个Token,如果没有Token可拿了就阻塞或者拒绝服务.
令牌添加速度支持动态变化,实时控制处理的速率.
令牌桶算法的问题:
- 令牌满了,请求无法处理
- 桶容量问题
- 令牌添加速度控制问题
3. 漏桶和令牌桶算法对比
- 令牌桶是按照固定速率往桶中添加令牌,请求是否被处理需要看桶中令牌是否足够,当令牌数减为零时则拒绝新的请求;
- 漏桶则是按照常量固定速率流出请求,流入请求速率任意,当流入的请求数累积到漏桶容量时,则新流入的请求被拒绝;
- 令牌桶限制的是平均流入速率(允许突发请求,只要有令牌就可以处理,支持一次拿3个令牌,4个令牌),并允许一定程度突发流量;
- 漏桶限制的是常量流出速率(即流出速率是一个固定常量值,比如都是1的速率流出,而不能一次是1,下次又是2),从而平滑突发流入速率;
- 令牌桶允许一定程度的突发,而漏桶主要目的是平滑流入速率;
- 两个算法实现可以一样,但是方向是相反的,对于相同的参数得到的限流效果是一样的。
4. 计数器
主要用来限制总并发数,比如数据库连接池、线程池、并发数;只要全局总请求数超过设定的阀值则进行限流,是简单粗暴的总数量限流,而不是平均速率限流。
- 限制总并发数(比如数据库连接池、线程池)
- 限制瞬时并发数(如nginx的limit_conn模块,用来限制瞬时并发连接数)
- 限制时间窗口内的平均速率(如Guava的RateLimiter、nginx的limit_req模块,限制每秒的平均速率)
- 限制远程接口调用速率
- 限制MQ的消费速率。
- 可以根据网络连接数、网络流量、CPU或内存负载等来限流
总结一下:
从流控算法上看,主要有三个核心要素:
- 可用容量
- 速率控制
- 容量打满后的处理策略:丢弃 or 阻塞
流控算法只是流量控制中核心的一环,并不是全部。实际应用上,需要结合实际的业务场景,采用适合的流控算法实现流量控制!
四、流控中心设计
通过上面需求分析、业界对标&对比、流控算法对比,我们规划了流控中心的产品特性,在此基础上完成一个V1.0版本的流控框架实现,同时准备开源出去,让更多的人可以直接使用。
管理时(设计时):
- 提供统一的流控策略定义,流控策略中可以指定使用具体控制方式,支持QPS、指定时间内访问量、并发数、延迟时间四种控制方式
- 支持对API网关服务、RPC服务、MQ等不同的主体,绑定不同的流控策略和阈值。
- 对于API网关服务,支持按服务、来源、用户、集群、进程设置QPS流量控制策略,同时支持按指定时间范围(分钟、小时、天)设置访问次数对应的流控策略。
- 对于RPC服务,支持按服务、集群、进程设置QPS流量控制策略,同时支持按指定时间范围(分钟、小时、天)设置访问次数对应的流控策略。
- 对于MQ,支持按队列、集群、进程设置消息消费的并发流量控制策略,同时支持延迟消费控制策略。
- 触发流控策略后,支持一种或者多种处理策略:请求失败、请求等待、预警等
- 流控策略和阈值支持动态调配,通过配置中心实时同步到各个流控模块,配置动态实时生效。
- 提供统一的流控日志查看功能,支持根据流控主体、时间实时查询流控触发情况。
运行时:
- 提供可独立运行的限流模块程序,Host在各类服务容器(API网关、RPC服务框架、MQ)中独立运行
- 运行时支持对QPS、指定时间内访问量、并发数、延迟时间四种流量控制方式,根据流控策略的定义实时控制流量。
- 提供对应用集群(全局)类的流控管理及应用进程(进程级)的流控管理
- 触发流控后,支持实时将监控、预警信息实时推送到监控预警平台
- 流控策略和阈值调整后,通过配置中心实时同步到各个限流模块程序,实时生效。
这是目前我们流控中心大致的规划和整理,其实技术原型代码我们已经写出来了,昨天完成UT通过了,下一篇博客我们将把这个流控框架一点点分享给大家。
提前剧透一下,我们借鉴了Git的RateLimiters
https://github.com/robertmircea/RateLimiters
周国庆
2018/5/16
统一流控服务开源-1:场景&业界做法&算法篇的更多相关文章
- 统一流控服务开源:基于.Net Core的流控服务
先前有一篇博文,梳理了流控服务的场景.业界做法和常用算法 统一流控服务开源-1:场景&业界做法&算法篇 最近完成了流控服务的开发,并在生产系统进行了大半年的验证,稳定可靠.今天整理一下 ...
- Net Core的流控服务
统一流控服务开源:基于.Net Core的流控服务 先前有一篇博文,梳理了流控服务的场景.业界做法和常用算法 统一流控服务开源-1:场景&业界做法&算法篇 最近完成了流控服务的开发 ...
- Spring Cloud & Alibaba 实战 | 第十二篇: 微服务整合Sentinel的流控、熔断降级,赋能拥有降级功能的Feign新技能熔断,实现熔断降级双剑合璧(JMeter模拟测试)
目录 一. Sentinel概念 1. 什么是Sentinel? 2. Sentinel功能特性 3. Sentinel VS Hystrix 二. Docker部署Sentinel Dashboar ...
- 性能百万/s:腾讯轻量级全局流控方案详解
WeTest 导读 全新的全局流控实现方案,既解决了目前流控的实现难点,同时保证运行稳定且流控准确的前提下,实现更简单,部署成本更低,容灾能力更强. 该方案组件化之后,可以推广到别的有需要的部门使用, ...
- 性能百万/s:腾讯轻量级全局流控方案详解【转自Wetest】
阿里用的方案是在nginx中配置限流(限流功能模块是自己开发的),流量统计线上是有监控打通的,具体的限流值是通过线上流量表现+线下性能测试(模拟线上场景)测试得出的. 全新的全局流控实现方案,既解决了 ...
- sentinel 集群流控原理
为什么需要集群流控呢?假设需要将某个API的总qps限制在100,机器数可能为50,这时很自然的想到使用一个专门的server来统计总的调用量,其他实例与该server通信来判断是否可以调用,这就是基 ...
- Sentinel 发布里程碑版本,添加集群流控功能
自去年10月底发布GA版本后,Sentinel在近期发布了另一个里程碑版本v1.4(最新的版本号是v1.4.1),加入了开发者关注的集群流控功能. 集群流控简介 为什么要使用集群流控呢?假设我们希望给 ...
- 详解API Gateway流控实现,揭开ROMA平台高性能秒级流控的技术细节
摘要:ROMA平台的核心系统ROMA Connect源自华为流程IT的集成平台,在华为内部有超过15年的企业业务集成经验. 本文分享自华为云社区<ROMA集成关键技术(1)-API流控技术详解& ...
- 详解ROMA Connect API 流控实现技术
摘要:本文将详细描述API Gateway流控实现,揭开高性能秒级流控的技术细节. 1.概述 ROMA平台的核心系统ROMA Connect源自华为流程IT的集成平台,在华为内部有超过15年的企业业务 ...
随机推荐
- Ubuntu 14 安装Skype 4.3
Ubuntu 14 安装Skype 4.3Step 1: 删除老版本sudo apt-get remove skype skype-bin:i386 skype:i386 sudo apt-get i ...
- C语言函数strstr()分析及实现
原型:char *strstr(const char *str1, const char *str2); #include<string.h> 找出str2字符串在str1字符串中第一次出 ...
- Android虚拟机 USB转串口调试方法
有时候需要在虚拟机调试串口,首先安装串口的驱动程序(不知道的话可以用驱动精灵),然后打开设备管理器找到驱动,查看驱动使用的端口(比如COM3),虚拟机需要在命令行启动: 将SDK下的tools文件夹加 ...
- Java进阶(五十二)利用LOG4J生成服务日志
Java进阶(五十二)利用LOG4J生成服务日志 前言 由于论文写作需求,需要进行流程挖掘.前提是需要有真实的事件日志数据.真实的事件日志数据可以用来发现.监控和提升业务流程. 为了获得真实的事件日志 ...
- 【Visual C++】游戏编程学习笔记之五:单一背景滚动
本系列文章由@二货梦想家张程 所写,转载请注明出处. 本文章链接:http://blog.csdn.net/terence1212/article/details/44224963 作者:ZeeCod ...
- iOS下FMDB的多线程操作(一)
iOS中一些时间比较长的操作都应该放在子线程中,以避免UI的卡顿.而sqlite 是非线程安全的,故在多线程中不能共用同一个数据库连接,否则会导致EXC_BAD_ACCESS.所以我们可以在子线程中创 ...
- objc直接通过指针访问对象实例变量
我们现在来做一件被认为是very bad的事情,如题所示:无论实例变量是私有的.保护的都可以通过地址访问到,并且还可以修改之.这可以称之为所谓的"超级键值编码". 首先上代码: # ...
- 如何设置静态IP
首先在CMD命令行ipconfig查看临时分配的IP地址: 然后打开我的"网络"--->"本地连接"--->IPv4--->属性 电信DNS劫 ...
- ZYThumbnailTableView类似于小型阅读器
Demo github地址: https://github.com/liuzhiyi1992/ZYThumbnailTableView 原文地址:http://zyden.vicp.cc/zythu ...
- Log4j运用于代码中
在JAVA代码中,我们要打印输出语句的时候,我们经常会使用System.out.print(),但是在项目开发完后,这些代码就会影响项目的运行效率,所以Log4j就派上用场了.话不多说,直接上代码. ...