思考并整理分布式业务的解决方案,有问题请帮忙指出,谢谢!
设定一个场景,假如一个商品接口在某段时间突然上升,会怎么办?
生活中的例子来说,假设冰墩墩在当天晚上上热搜之后,迅速有十几万人去淘宝下单购买,此时并没有做好对该商品的缓存预热以及准备,如何操作?
对于这个问题,在电商高并发系统中,对接口的保护一般采用:缓存
、限流
、降级
来操作。
假设该接口已经接受过风控的处理,过滤掉一半的机器人脚本请求,剩下都是人为的下单请求。
限流
主要的目的是通过对并发访问/请求进行限速,或者对一个时间窗口内的请求进行限速,一旦达到限制速率则可以拒绝服务、排队或等待、降级等处理。
漏桶算法
是当请求到达时直接放入漏桶,如果当前容量已达到上限(限流值),则进行丢弃或其他策略(触发限流策略)。漏桶以固定的速率(根据服务吞吐量)进行释放访问请求(即请求通过),直到漏桶为空。
漏斗算法的思想就是,不管你来多少请求,我的接口消费速度一定是小于等于流出速率的阈值的。
可以基于消息队列来实现。
令牌桶算法
是程序以v(v = 时间周期 / 限流值)的速度向令牌桶中增加令牌,直到令牌桶满,请求到达时向令牌桶请求令牌,如果获取成功则通过请求,如果获取失败触发限流策略。
令牌桶算法和漏斗算法的思想差别在于,前者可以允许突发请求的发生。
滑窗算法
是将一个时间周期分为N个小周期,分别记录每个小周期内访问次数,并且根据时间滑动删除过期的小周期。
如下图所示,假设时间周期为1分钟,将1分钟再分为2个小周期,统计每个小周期的访问数量,则可以看到,第一个时间周期内,访问数量为75,第二个时间周期内,访问数量为100,如果一个时间周期内所有的小周期总和超过100的话,则会触发限流策略。
Sentinel的实现 和 TCP滑窗。
Nginx
限流采用的是漏桶算法。
它可以根据客户端特征,限制其访问频率,客户端特征主要指 IP
、UserAgent
等。使用 IP
比 UserAgent
更可靠,因为 IP
无法造假,UserAgent
可随意伪造。
limit_req模块基于IP:Module ngx_http_limit_req_module (nginx.org)
tgngine:ngx_http_limit_req_module - The Tengine Web Server (taobao.org)
Java 并发库 的 Semaphore
可以很轻松完成信号量控制,Semaphore
可以控制某个资源可被同时访问的个数,通过 acquire()
获取一个许可,如果没有就等待,而 release()
释放一个许可。
假如我们对外提供一个服务接口,允许最大并发数为40,我们可以这样:
private final Semaphore permit = new Semaphore(40, true);
public void process(){
try{
permit.acquire();
//TODO 处理业务逻辑
} catch (InterruptedException e) {
e.printStackTrace();
} finally {
permit.release();
}
}
具体的 Semaphore
实现参考源码。
不管是用MQ中间件,或是Redis的List实现的消息队列,都可以作为一个 缓冲队列
来使用。思想就是基于漏斗算法。
当对于一个接口请求达到一定阈值时,就可以启用消息队列来进行接口数据的缓冲,并根据服务的吞吐量来消费数据。
在接口做好风控的前提下,发现了接口请求的并发量迅速上升,我们可以启用兜底方案,进行服务降级。
一般服务降级应该用来对一些 不重要 或 不紧急 的服务或任务进行服务的 延迟使用 或 暂停使用。
比如淘宝双11前,就不可以查询三个月前的订单,对边缘业务进行降级,保证核心业务的高可用。
在接口请求并发量大于阈值,或是接口出现大量失败请求等等突发情况,可以拒绝一些访问请求。
在实现服务降级之后,对于突增流量我们可以继续注册多个消费者服务来应对并发量,之后我们再对一些服务器进行慢加载。
降级具体实现参考其他文章。
在接口做好风控的前提下,发现了接口请求的并发量迅速上升,我们可以分以下几个操作执行:
假设我们操作的是一个库存接口,此时数据库中只有100个库存。
那假如此时我们将一条数据放入缓存中,如果所有的请求都来访问这个缓存,那它还是被打挂,我们该怎么操作?
第一种想法,读写分离。
使用Redis的哨兵集群模式来进行主从复制的读写分离操作。读的操作肯定大于写操作,等库存被消费到0时,读操作直接快速失败。
第二种想法,负载均衡。
在缓存数据后,如果所有请求都来缓存中操作这个库存,不管是加悲观锁还是乐观锁,并发率都很低,此时我们可以对这个库存进行拆分。
我们可以参照 ConcurrentHashMap
中的 counterCells
变量的设计思想,将100个库存拆分到10个缓存服务中,每个缓存服务有10个缓存,然后我们再对请求进行负载均衡到各个缓存服务上。
但是这种方式会有问题,如果大部分用户被hash到同一个缓存上,导致其他缓存没有被消费,却返回没有库存,这是不合理的。
第三种想法,page cache。
大部分软件架构其实都用到了这种方法,比如linux内核的硬盘写入、mysql的刷盘等等,即将短时间内的写操作聚合结果写入,所有的写操作在缓存内完成。
原网址: 访问
创建于: 2023-01-06 14:45:24
目录: default
标签: 无
未标明原创文章均为采集,版权归作者所有,转载无需和我联系,请注明原出处,南摩阿彌陀佛,知识,不只知道,要得到
java windows火焰图_mob64ca12ec8020的技术博客_51CTO博客 - 在windows下不可行,不知道作者是怎样搞的 监听SpringBoot 服务启动成功事件并打印信息_监听springboot启动完毕-CSDN博客 SpringBoot中就绪探针和存活探针_management.endpoint.health.probes.enabled-CSDN博客 u2u转换板 - 嘉立创EDA开源硬件平台 Spring Boot 项目的轻量级 HTTP 客户端 retrofit 框架,快来试试它!_Java精选-CSDN博客 手把手教你打造一套最牛的知识笔记管理系统! - 知乎 - 想法有重合-理论可参考 安宇雨 闲鱼 机械键盘 客制化 开贴记录 文本 linux 使用find命令查找包含某字符串的文件_beijihukk的博客-CSDN博客_find 查找字符串 ---- mac 也适用 安宇雨 打字音 记录集合 B站 bilibili 自行搭建 开坑 真正的客制化 安宇雨 黑苹果开坑 查找工具包maven pom 引用地 工具网站 Dantelis 介绍的玩轴入坑攻略 --- 关于轴的一些说法 --- 非官方 ---- 心得而已 --- 长期开坑更新 [本人问题][新开坑位]关于自动化测试的工具与平台应用 机械键盘 开团 网站记录 -- 能做一个收集的程序就好了 不过现在没时间 -- 信息大多是在群里发的 - 你要让垃圾佬 都去一个地方看难度也是很大的 精神支柱 [超级前台]sprinbboot maven superdesk-app 记录 [信息有用] [环境准备] [基本完成] [sebp/elk] 给已创建的Docker容器增加新的端口映射 - qq_30599553的博客 - CSDN博客 [正在研究] Elasticsearch, Logstash, Kibana (ELK) Docker image documentation elasticsearch centos 安装记录 及 启动手记 正式服务器 39 elasticsearch 问题合集 不断更新 6.1.1 | 6.5.1 两个版本 博客程序 - 测试 - bug记录 等等问题 laravel的启动过程解析 - lpfuture - 博客园 OAuth2 Server PHP 用 Laravel 搭建带 OAuth2 验证的 RESTful 服务 | Laravel China 社区 - 高品质的 Laravel 和 PHP 开发者社区 利用Laravel 搭建oauth2 API接口 附 Unauthenticated 解决办法 - 煮茶的博客 - SegmentFault 思否 使用 OAuth2-Server-php 搭建 OAuth2 Server - 午时的海 - 博客园 基于PHP构建OAuth 2.0 服务端 认证平台 - Endv - 博客园 Laravel 的 Artisan 命令行工具 Laravel 的文件系统和云存储功能集成 浅谈Chromium中的设计模式--终--Observer模式 浅谈Chromium中的设计模式--二--pre/post和Delegate模式 浅谈Chromium中的设计模式--一--Chromium中模块分层和进程模型 DeepMind 4 Hacking Yourself README.md update 20211011
Laravel China 简书 知乎 博客园 CSDN博客 开源中国 Go Further Ryan是菜鸟 | LNMP技术栈笔记 云栖社区-阿里云 Netflix技术博客 Techie Delight Linkedin技术博客 Dropbox技术博客 Facebook技术博客 淘宝中间件团队 美团技术博客 360技术博客 古巷博客 - 一个专注于分享的不正常博客 软件测试知识传播 - 测试窝 有赞技术团队 阮一峰 语雀 静觅丨崔庆才的个人博客 软件测试从业者综合能力提升 - isTester IBM Java 开发 使用开放 Java 生态系统开发现代应用程序 pengdai 一个强大的博主 HTML5资源教程 | 分享HTML5开发资源和开发教程 蘑菇博客 - 专注于技术分享的博客平台 个人博客-leapMie 流星007 CSDN博客 - 舍其小伙伴 稀土掘金 Go 技术论坛 | Golang / Go 语言中国知识社区
最新评论