简单地说,过载是外部请求对系统的访问量突然激增,造成请求堆积,服务不可用,最终导致系统崩溃。本文主要分析引入Cache可能造成的服务过载,并讨论相关的预防、恢复策略。Cache在现代系统中使用广泛,由此引入的服务过载隐患无处不在,但却非常隐蔽,容易被忽视。本文希望能为开发者在设计和编写相关类型应用,以及服务过载发生处理时能够有章可循。
一个服务过载案例
本文讨论的案例是指存在正常调用关系的两个系统(假设调用方为A系统,服务方为B系统),A系统对B系统的访问突然超出B系统的承受能力,造成B系统崩溃。造成服务过载的原因很多,这里分析的是严重依赖Cache的系统服务过载。首先来看一种包含Cache的体系结构(如下图所示)。
A系统依赖B系统的读服务,A系统是60台机器组成的集群,B系统是6台机器组成的集群,之所以6台机器能够扛住60台机器的访问,是因为A系统并不是每次都访问B,而是首先请求Cache,只有Cache的相应数据失效时才会请求B。
这正是Cache存在的意义,它让B系统节省了大量机器;如果没有Cache,B系统不得不组成60台机器的集群,如果A也同时依赖除B系统外的另一个系统(假设为C系统)呢?那么C系统也要60台机器,放大的流量将很快耗尽公司的资源。
然而Cache的引入也不是十全十美的,这个结构中如果Cache发生问题,全部的流量将流向依赖方,造成流量激增,从而引发依赖系统的过载。
回到A和B的架构,造成服务过载的原因至少有下面三种:
- B系统的前置代理发生故障或者其他原因造成B系统暂时不可用,等B系统系统服务恢复时,其流量将远远超过正常值。
- Cache系统故障,A系统的流量将全部流到B系统,造成B系统过载。
- Cache故障恢复,但这时Cache为空,Cache瞬间命中率为0,相当于Cache被击穿,造成B系统过载。
第一个原因不太好理解,为什么B系统恢复后流量会猛增呢?主要原因就是缓存的超时时间。当有数据超时的时候,A系统会访问B系统,但是这时候B系统偏偏故障不可用,那么这个数据只好超时,等发现B系统恢复时,发现缓存里的B系统数据已经都超时了,都成了旧数据,这时当然所有的请求就打到了B。
下文主要介绍服务过载的预防和发生后的一些补救方法,以预防为主,从调用方和服务方的视角阐述一些可行方案。
服务过载的预防
所谓Client端指的就是上文结构中的A系统,相对于B系统,A系统就是B系统的Client,B系统相当于Server。
Client端的方案
针对上文阐述的造成服务过载的三个原因:B系统故障恢复、Cache故障、Cache故障恢复,我们看看A系统有哪些方案可以应对。
合理使用Cache应对B系统宕机
一般情况下,Cache的每个Key除了对应Value,还对应一个过期时间T,在T内,get操作直接在Cache中拿到Key对应Value并返回。但是在T到达时,get操作主要有五种模式:
1. 基于超时的简单(stupid)模式
在T到达后,任何线程get操作发现Cache中的Key和对应Value将被清除或标记为不可用,get操作将发起调用远程服务获取Key对应的Value,并更新写回Cache,然后get操作返回新值;如果远程获取Key-Value失败,则get抛出异常。
为了便于理解,举一个码头工人取货的例子:5个工人(线程)去港口取同样Key的货(get),发现货已经过期被扔掉了,这时5个工人各自分别去对岸取新货,然后返回。
2. 基于超时的常规模式
在T到达后,Cache中的Key和对应Value将被清除或标记为不可用,get操作将调用远程服务获取Key对应的Value,并更新写回Cache;此时,如果另一个线程发现Key和Value已经不可用,get操作还需要判断有没有其他线程发起了远程调用,如果有,那么自己就等待,直到那个线程远程获取操作成功,Cache中得Key变得可用,get操作返回新的Value。如果远程获取操作失败,则get操作抛出异常,不会返回任何Value。
还是码头工人的例子:5个工人(线程)去港口取同样Key的货(get),发现货已经过期被扔掉了,那么只需派出一个人去对岸取货,其他四个人在港口等待即可,而不用5个人全去。
基于超时的简单模式和常规模式区别在于对于同一个超时的Key,前者每个get线程一旦发现Key不存在,则发起远程调用获取值;而后者每个get线程发现Key不存在,则还要判断当前是否有其他线程已经发起了远程调用操作获取新值,如果有,自己就简单的等待即可。
显然基于超时的常规模式比基于超时的简单模式更加优化,减少了超时时并发访问后端的调用量。
实现基于超时的常规模式就需要用到经典的Double-checked locking惯用法了。
3. 基于刷新的简单(stupid)模式
在T到达后,Cache中的Key和相应Value不动,但是如果有线程调用get操作,将触发refresh操作,根据get和refresh的同步关系,又分为两种模式:
- 同步模式:任何线程发现Key过期,都触发一次refresh操作,get操作等待refresh操作结束,refresh结束后,get操作返回当前Cache中Key对应的Value。注意refresh操作结束并不意味着refresh成功,还可能抛了异常,没有更新Cache,但是get操作不管,get操作返回的值可能是旧值。
- 异步模式:任何线程发现Key过期,都触发一次refresh操作,get操作触发refresh操作,不等refresh完成,直接返回Cache中的旧值。
举上面码头工人的例子说明基于刷新的常规模式:这次还是5工人去港口取货,这时货都在,但是已经旧了,这时5个工人有两种选择:
- 5个人各自去远程取新货,如果取货失败,则拿着旧货返回(同步模式)
- 5个人各自通知5个雇佣工去取新货,5个工人拿着旧货先回(异步模式)
4. 基于刷新的常规模式
在T到达后,Cache中的Key和相应Value都不会被清除,而是被标记为旧数据,如果有线程调用get操作,将触发refresh更新操作,根据get和refresh的同步关系,又分为两种模式:
- 同步模式:get操作等待refresh操作结束,refresh结束后,get操作返回当前Cache中Key对应的Value,注意:refresh操作结束并不意味着refresh成功,还可能抛了异常,没有更新Cache,但是get操作不管,get操作返回的值可能是旧值。如果其他线程进行get操作,Key已经过期,并且发现有线程触发了refresh操作,则自己不等refresh完成直接返回旧值。
- 异步模式:get操作触发refresh操作,不等refresh完成,直接返回Cache中的旧值。如果其他线程进行get操作,发现Key已经过期,并且发现有线程触发了refresh操作,则自己不等refresh完成直接返回旧值。
再举上面码头工人的例子说明基于刷新的常规模式:这次还是5工人去港口取货,这时货都在,但是已经旧了,这时5个工人有两种选择:
- 派一个人去远方港口取新货,其余4个人拿着旧货先回(同步模式)。
- 5个人通知一个雇佣工去远方取新货,5个人都拿着旧货先回(异步模式)。
基于刷新的简单模式和基于刷新的常规模式区别就在于取数线程之间能否感知当前数据是否正处在刷新状态,因为基于刷新的简单模式中取数线程无法感知当前过期数据是否正处在刷新状态,所以每个取数线程都会触发一个刷新操作,造成一定的线程资源浪费。
而基于超时的常规模式和基于刷新的常规模式区别在于前者过期数据将不能对外访问,所以一旦数据过期,各线程要么拿到数据,要么抛出异常;后者过期数据可以对外访问,所以一旦数据过期,各线程要么拿到新数据,要么拿到旧数据。
5. 基于刷新的续费模式
该模式和基于刷新的常规模式唯一的区别在于refresh操作超时或失败的处理上。在基于刷新的常规模式中,refresh操作超时或失败时抛出异常,Cache中的相应Key-Value还是旧值,这样下一个get操作到来时又会触发一次refresh操作。
在基于刷新的续费模式中,如果refresh操作失败,那么refresh将把旧值当成新值返回,这样就相当于旧值又被续费了T时间,后续T时间内get操作将取到这个续费的旧值而不会触发refresh操作。
基于刷新的续费模式也像常规模式那样分为同步模式和异步模式,不再赘述。
下面讨论这5种Cache get模式在服务过载发生时的表现,首先假设如下:
- 假设A系统的访问量为每分钟M次。
- 假设Cache能存Key为C个,并且Key空间有N个。
- 假设正常状态下,B系统访问量为每分钟W次,显然W\<\<M。
这时因为某种原因,比如B长时间故障,造成Cache中得Key全部过期,B系统这时从故障中恢复,五种get模式分析表现分析如下:
- 在基于超时和刷新的简单模式中,B系统的瞬间流量将达到和A的瞬时流量M大体等同,相当于Cache被击穿。这就发生了服务过载,这时刚刚恢复的B系统将肯定会被大流量压垮。
- 在基于超时和刷新的常规模式中,B系统的瞬间流量将和Cache中Key空间N大体等同。这时是否发生服务过载,就要看Key空间N是否超过B系统的流量上限了。
- 在基于刷新的续费模式中,B系统的瞬间流量为W,和正常情况相同而不会发生服务过载。实际上,在基于刷新的续费模式中,不存在Cache Key全部过期的情况,就算把B系统永久性地干掉,A系统的Cache也会基于旧值长久的平稳运行。
第3点,B系统不会发生服务过载的主要原因是基于刷新的续费模式下不会出现chache中的Key全部长时间过期的情况,即使B系统长时间不可用,基于刷新的续费模式也会在一个过期周期内把旧值当成新值继续使用。所以当B系统恢复时,A系统的Cache都处在正常工作状态。
从B系统的角度看,能够抵抗服务过载的基于刷新的续费模式最优。
从A系统的角度看,由于一般情况下A系统是一个高访问量的在线web应用,这种应用最讨厌的一个词就是“线程等待”,因此基于刷新的各种异步模式较优。
综合考虑,基于刷新的异步续费模式是首选。
然而凡是有利就有弊,有两点需要注意的地方:
- 基于刷新模式最大的缺点是Key-Value一旦放入Cache就不会被清除,每次更新也是新值覆盖旧值,JVM GC永远无法对其进行垃圾收集,而基于超时的模式中,Key-Value超时后如果新的访问没有到来,内存是可以被GC垃圾回收的。所以如果你使用的是寸土寸金的本地内存做Cache就要小心了。
- 基于刷新的续费模式需要做好监控,不然有可能Cache中的值已经和真实的值相差很远了,应用还以为是新值而使用。
关于具体的Cache,来自Google的Guava本地缓存库支持上文的第二种、第四种和第五种get操作模式。
但是对于Redis等分布式缓存,只提供原始的get、set方法,而提供的get仅仅是获取,与上文提到的五种get操作模式不是一个概念。开发者想用这五种get操作模式的话不得不自己封装和实现。
五种get操作模式中,基于超时和刷新的简单模式是实现起来最简单的模式,但遗憾的是这两种模式对服务过载完全无免疫力,这可能也是服务过载在大量依赖缓存的系统中频繁发生的一个重要原因吧。
本文之所以把第1、3种模式称为stupid模式,是想强调这种模式应该尽量避免,Guava里面根本没有这种模式,而Redis只提供简单的读写操作,很容易就把系统实现成了这种方式。
应对分布式Cache宕机
如果是Cache直接挂了,那么就算是基于刷新的异步续费模式也无能为力了。这时A系统铁定无法对Cache进行存取操作,只能将流量完全打到B系统,B系统面对服务过载在劫难逃......
本节讨论的预防Cache宕机仅限于分布式Cache,因为本地Cache一般和A系统应用共享内存和进程,本地Cache挂了A系统也挂了,不会出现本地Cache挂了而A系统应用正常的情况。
首先,A系统请求线程检查分布式Cache状态,如果无应答则说明分布式Cache挂了,则转向请求B系统,这样一来大流量将压垮B系统。这时可选的方案如下:
- A系统的当前线程不请求B系统,而是打个日志并设置一个默认值。
- A系统的当前线程按照一定概率决定是否请求B系统。
- A系统的当前线程检查B系统运行情况,如果良好则请求B系统。
方案1最简单,A系统知道如果没有Cache,B系统可能扛不住自己的全部流量,索性不请求B系统,等待Cache恢复。但这时B系统利用率为0,显然不是最优方案,而且当请求的Value不容易设置默认值时,这个方案就不行了。
方案2可以让一部分线程请求B系统,这部分请求肯定能被B系统hold住。可以保守的设置这个概率 u =(B系统的平均流量)/(A系统的峰值流量)
方案3是一种更为智能的方案,如果B系统运行良好,当前线程请求;如果B系统过载,则不请求,这样A系统将让B系统处于一种宕机与不宕机的临界状态,最大限度挖掘B系统性能。这种方案要求B系统提供一个性能评估接口返回Yes和No,Yes表示B系统良好,可以请求;No表示B系统情况不妙,不要请求。这个接口将被频繁调用,必须高效。
方案3的关键在于如何评估一个系统的运行状况。一个系统中当前主机的性能参数有CPU负载、内存使用率、Swap使用率、GC频率和GC时间、各个接口平均响应时间等,性能评估接口需要根据这些参数返回Yes或者No,是不是机器学习里的二分类问题?
相关推荐
综上所述,《Web应用中的海量数据访问缓存技术》不仅提供了对现有缓存技术的全面概述,更重要的是,它创新性地提出了一种整合线程池、连接池和数据Cache技术的框架模型,有效解决了Web应用在处理海量数据时面临的...
此外,利用案例研究,如分析亚马逊、谷歌等公司的数据中心如何处理海量请求,也能激发学生的兴趣,深化对这两个概念的理解。 在课堂讨论中,鼓励学生提出自己的观点和解决方案,促进他们批判性思维的发展。教师可以...
分布式文件系统在实践中有着广泛的应用,以下是一些典型的分布式文件系统案例: - **GPFS**: IBM开发的高性能并行文件系统,常用于大型集群环境中。 - **Lustre**: 广泛应用于高性能计算领域的并行文件系统。 - **...
#### 十一、案例研究 **13.1 概要** - 提供具体的案例分析,展示HBase在实际应用中的使用场景和解决方案。 **13.2 Schema设计** - 展示如何针对特定的应用场景进行合理的Schema设计。 **13.3 性能/故障排除** ...
Matlab领域上传的视频是由对应的完整代码运行得来的,完整代码皆可运行,亲测可用,适合小白; 1、从视频里可见完整代码的内容 主函数:main.m; 调用函数:其他m文件;无需运行 运行结果效果图; 2、代码运行版本 Matlab 2019b;若运行有误,根据提示修改;若不会,私信博主; 3、运行操作步骤 步骤一:将所有文件放到Matlab的当前文件夹中; 步骤二:双击打开main.m文件; 步骤三:点击运行,等程序运行完得到结果; 4、仿真咨询 如需其他服务,可私信博主; 4.1 博客或资源的完整代码提供 4.2 期刊或参考文献复现 4.3 Matlab程序定制 4.4 科研合作
SAE AS85049F+Connector Accessories, Electrical General Specification for+2021-04(1).pdf
NAVMAT P-9492 .pdf
内容概要:《有货App》产品立项说明书详细阐述了有货App的产品定位、目标用户、主要功能及市场分析。有货App隶属于YOHO!集团,起初为潮流杂志,逐渐转型为集媒体、零售、活动于一体的潮流营销平台。其核心定位为时尚穿搭,面向20~39岁追求潮流的年轻群体,提供正品国际潮牌、明星潮牌的一站式购买服务,并设有时尚潮流穿搭社区、正品鉴定和二手买卖平台。市场分析表明,全球潮牌市场呈两位数增长,尤其是中国市场增速显著,国潮崛起,95后成消费主力,推动潮牌需求上升。有货App的优势在于丰富的潮牌种类和内容基础,但社区互动少、存在假货现象、物流时效差是其劣势。产品规划分为四个版本迭代,逐步完善电商、正品鉴定、社区互动及二手买卖功能。 适合人群:20~39岁追求时尚穿搭、潮流生活的年轻群体,包括上班族、学生及时尚爱好者。 使用场景及目标:①满足用户一站式购买全球潮流品牌的需求;②提供时尚潮流穿搭社区,供用户分享交流穿搭心得;③确保用户购买正品,提供专业的正品鉴定服务;④搭建二手交易平台,方便用户出售或购买二手潮牌服饰。 阅读建议:此文档详细介绍了有货App的市场背景、产品定位及功能规划,适合产品经理、市场分析师及相关从业人员阅读,以了解潮牌电商市场的发展趋势及有货App的竞争策略。
内容概要:本文介绍了一款基于C#编写的485转Web API服务器框架,该框架集成了IoT技术和高性能高并发特性。框架主要特点包括强大的数据库支持(EF6+mssql),独立的WEB API服务,丰富的协议扩展性(支持Modbus、Modbus RTU等),便捷的MVC服务与硬件驱动,创新的设备轮询机制,灵活的API任务管理和便捷的运行与配置。此外,框架提供了完备的文档和技术支持,并进行了多项升级,如自适应服务规则、一键启动与自动配置、修复数据读取问题、设备标识增强和开放数据事件接口等。 适合人群:具备一定编程基础,尤其是熟悉C#和IoT技术的开发人员,适用于工业物联网系统的集成和开发。 使用场景及目标:该框架主要用于工业物联网项目的快速落地,特别是在需要高性能和灵活扩展的应用场景中。它可以用于构建能够处理大量并发连接的物联网后端系统,支持多种数据库和协议,简化设备连接管理和任务调度。 其他说明:框架不仅提供了详细的使用说明和技术支持,还在性能优化和资源管理方面做了很多改进,使得开发者可以更加专注于业务逻辑的实现。
一文了解 MCP、A2A、ANP
内容概要:本文详细介绍了如何使用Comsol多物理场仿真软件构建煤层瓦斯汽固耦合模型。文章首先解释了煤层瓦斯的基本概念及其重要性,随后逐步展示了如何在Comsol中定义几何结构、设置材料属性、添加物理场(如达西流和Langmuir吸附)、进行求解及结果分析。特别强调了渗透率动态变化、吸附解吸机制、耦合求解技巧以及模型验证方法。通过这些步骤,可以精确模拟瓦斯在煤层内的运移规律,为煤矿的安全开采提供科学依据。 适合人群:从事煤矿工程、地质勘探、能源开发等领域研究人员和技术人员,尤其是那些希望深入了解煤层瓦斯行为并对现有开采工艺进行优化的人群。 使用场景及目标:适用于需要评估煤层瓦斯风险、优化瓦斯抽采方案、提高煤炭资源利用率的实际工程项目。通过对煤层瓦斯汽固耦合模型的研究,可以帮助企业更好地规划开采活动,确保生产安全的同时最大化经济效益。 其他说明:文中提供的代码片段和建模思路不仅有助于初学者快速入门Comsol仿真工具,也为有经验的用户提供了一些实用的小贴士,如避免常见错误、提升求解效率等。此外,还提到了一些高级特性,如参数扫描界面开发、集群计算等功能的应用。
系统名称:数据结构课堂考勤管理系统 技术栈:JSP技术、MySQL数据库、SSM框架 系统功能:管理员可以通过系统后台录入学生及教师信息,包括学号、工号以及个人基础资料,同时可以通过课程管理添加课程信息,查看学生请假及签到信息;学生用户可以修改个人资料,结合课程信息实现在线签到提交,提交请假申请;教师用户可以通过管理界面查看学生请假信息并进行在线审批,查看学生签到信息及课程安排。 摘要:高校的不断扩张让在校学生数量不断增加,传统的人工点名签到的考勤管理模式已无法满足需求,同时手动录入的考勤管理模式浪费大量人力物力,也不便于考勤数据信息的管理和查询。考勤管理是高校教务管理工作的重点内容之一,通过考勤管理可以及时了解大学生在校的学习状态,培养学生自律自强的学习品格。结合高校内考勤管理的需求和重要性,利用互联网平台开发设计一款针对校内考勤管理的系统是非常有需求空间的。本文利用JSP技术开发设计了一款在线考勤管理系统,实现了学生与教师之间的信息互通,具备在线签到、在线请假以及课程信息查看等功能。同时结合国内外研究现状以及可行性分析,通过数据库结构的搭建以及系统的测试环节,实现了考勤管理系统的开发设计。
Java在线教育学习平台LW PPT
674222850524759拷貝漫畫-2.2.5(1).apk
内容概要:本文详细介绍了如何使用Simulink封装NXP MPC5634芯片的底层驱动,将复杂的寄存器配置转化为可视化的模块操作。文章通过具体实例展示了GPIO、PWM、ADC、CAN等常见外设的封装方法及其优势,如简化配置流程、提高开发效率、增强代码可读性和维护性。文中还分享了许多实践经验,如寄存器冲突检测、代码优化技巧以及调试工具的选择。 适合人群:从事汽车电子开发的技术人员,尤其是熟悉NXP MPC5634芯片并希望提高开发效率的研发人员。 使用场景及目标:适用于需要快速开发和调试汽车电子控制系统(如ECU)的团队。主要目标是减少底层驱动开发的时间成本,降低复杂度,提高系统的稳定性和可靠性。 其他说明:文章强调了Simulink封装库的实际应用价值,提供了大量代码片段和调试建议,帮助开发者更好地理解和掌握这一技术。此外,作者还提到了一些常见的陷阱和解决办法,有助于新手少走弯路。
内容概要:本文详细介绍了在MATLAB/Simulink环境下,针对微电网储能系统的锂电池SOC均衡问题提出的一种创新性的分段下垂控制策略。传统下垂控制存在收敛速度慢和充放电切换时母线电压波动大的问题。为解决这些问题,作者提出了将下垂曲线分为三个区域的方法:当SOC差超过5%时采用指数型下垂系数,2%-5%间使用二次曲线过渡,小于等于2%则保持线性控制。此外,引入了电压补偿机制以抑制母线电压波动,并通过仿真验证了该方法的有效性。结果显示,新的控制策略显著提高了SOC均衡的速度和平滑度,同时有效减少了母线电压波动。 适用人群:从事电力电子、微电网研究的技术人员以及对储能系统优化感兴趣的科研工作者。 使用场景及目标:适用于需要高效管理锂电池组SOC均衡并确保系统稳定的微电网项目。主要目标是在保证系统稳定性的同时提高SOC均衡效率,减少充放电切换时的电压波动。 其他说明:文中提供了详细的MATLAB/Simulink建模步骤和部分源代码片段,有助于读者理解和复现实验结果。
疫情控制途径.pptx
系统名称:基于SSM健身系统 技术栈:SSM框架、JSP技术、MySQL数据库 系统功能:管理员功能:系统用户信息管理、首页变幻图管理、课程信息管理、健身卡管理、健身器材管理、教练信息管理、购买及报名管理。用户功能:用户注册、健身卡信息查看及在线购买、健身教练信息查看、健身课程信息查看及在线报名、个人后台管理(包括健身卡办理信息管理、健身课程报名信息管理、个人资料维护和管理)。 摘要:随着人们对健康的重视度越来越高,健身经济的不断发展加速推动了健身房的扩张,与此同时多元化和便捷的健身方式也获得越来越多人的青睐,健身房的营销手段也逐渐从现在的宣传彩页推广逐渐转移到了线上平台,人们借助互联网平台实现了健身房健身设施、健身课程、教练信息以及健身卡优惠活动内容的查看和获取,通过线上平台实现了健身卡的办理以及健身课程的预约。相比传统的健身房管理模式,利用系统平台可以为用户提供更加便捷的在线报名及办卡服务,同时也提升健身房办卡及课程预约的管理效率。
内容概要:《10天精通DeepSeek实操手册》旨在帮助零基础用户在10天内掌握DeepSeek的使用方法,通过分阶段的学习目标逐步深入,涵盖AI认知、核心技能应用和实战变现。手册详细介绍了如何利用DeepSeek进行知识检索、内容生成、数据分析、创意设计等任务,并提供了具体的实操任务和案例,如生成论文大纲、优化会议纪要、处理合同审查等。此外,手册还提供了40个优质提示词库,覆盖学习提升、职场效率、生活助手等多个场景,以及学术资源导航和变现路径案例,帮助用户更好地应用DeepSeek解决实际问题。 适合人群:适合希望快速上手DeepSeek的零基础用户,尤其是希望通过AI工具提升工作效率、内容创作能力或寻求创收途径的人士。 使用场景及目标:①帮助用户破除对AI的恐惧,建立科学认知,了解AI的应用边界;②通过具体场景和任务,如论文写作、会议纪要整理、合同审查等,提高用户的实际操作能力;③提供变现指南,帮助用户通过AI工具开辟副业或优化现有业务,如代写商业计划书、制作AI使用指南、优化电商详情页等。 阅读建议:由于手册内容丰富且实用,建议读者结合自身需求,逐步实践每个阶段的任务,并灵活运用提供的提示词库和案例,确保在学习过程中不断积累经验和技能。同时,注意遵守相关法律法规,避免不当使用工具。
Delphi 12.3控件之ZhuTcp6.0.zip