本文由腾讯 WeTest 团队提供,更多资讯可直接戳链接查看:http://wetest.qq.com/lab/

微信号:TencentWeTest

1 何为过载

“过载” 一词,在海量服务的后台开发中,基本都会遇到。何为过载,即当前负载已经超过了系统的最大处理能力。例如,系统每秒能够处理的请求是 100 个,但实际每秒的请求量却是 1000 个,就可以判定系统出现了过载。

过载的定义看似简单,但却是处理过载问题的关键。对于任何其他问题,同样得抓住问题的本质,方可不偏离问题核心,万变而不离其宗。

2 过载后果

“过载” 的出现,会导致部分服务不可用,如果处置不当,极有可能引起服务完全不可用,乃至雪崩。

我们的系统中,由于是单线程状态机的处理模式,顺序处理所有链接的缓冲区消息,当出现处理能力的下降或者请求量大幅增加,导致处理能力小于请求量的情况下,消息就会在系统缓冲区中堆积,造成消息处理的延迟会持续增加,在正式环境中,链接数目较多,系统缓冲区较大,最终会导致消息处理延迟大到不可接受的程度,最终会导致处理的都是无效消息,造成服务不可用。

当然具体的业务需要具体的分析,把握住问题的影响,才能够做到一切尽在掌握,根据 “墨菲定律”,通常对后果的判断不应过于乐观,谨慎行事、考虑充分才能够做到胸有成竹。

3 过载原因

“过载” 的出现,不同系统模型的具体原因都会有所不同,例如 CPU 跑满,频繁读写导致 IO 瓶颈,内存耗尽,请求量突增等等。但究其根本原因,可以归结为两点:

1、处理能力的下降;

2、请求量的上升。

只有对自身系统的有更深层和透彻的了解,才能更好地考虑如何处置问题。“头疼医头,脚疼医脚” 的处理问题方式,只能解决一时之需,对症下药,才是解决问题的根本之道。

任何问题的保护行为可以依据事件发生的阶段分为:

1、发生前,预防;

2、发生时,处置;

3、发生后,恢复。

但在保护的措施中,都和业务的模型有着相关性,没有完全统一的方案,适合自己的才是最好的。

4 过载预防

在过载发生前的预防,就需在系统设计之初,依据具体的业务模型可以考虑预防过载的措施:

1、优化服务处理流程,降低处理资源消耗,提升自身处理能力;例如 CPU 消耗型服务,是否可以考虑优化算法,提升处理能力。

2、分离处理模块;将负载分担到不同的模块或者服务器;例如 IO 是瓶颈的服务,考虑是否可以将 IO 模块进行分离。

3、负载均衡;将请求量分流,降低单服请求量。

4、轻重模块分离;重要模块单独部署和处理,防止模块之间的互相影响。

5、前端防御;在前端控制请求频率,缓解后端压力;例如客户端可以做保护措施,控制聊天频率,点击操作失败,可以延时一段时间,才允许用户继续点击;前端服务发现后端出现过载问题,可选择性拒绝服务,降低后端压力。

6、使用缓冲区;缓冲区的使用,可以帮我们抵挡请求量的抖动,但缓冲区的使用同样也有很多技巧,并非越大越好。首先需要考虑内存,cpu 等资源的开销,业务的模型是否需要这么大的缓冲区。例如缓冲区过大,处理完整个缓冲区,都需要几十秒,而前端等待超时则为几秒,那么每次处理缓冲区的内容,都是旧的,前端认为都是超时,服务完全不可用。另外是后端却又处理成功,会导致系统信息不对称,从而导致更为严重的问题,例如,在游戏中购买道具的场景,前端扣用户的钱,认为超时失败而不给用户发对应的物品,后端却又执行成功了,严重运营问题就此产生。

7、做好监控,及时告警;例如当 CPU 达到 80% 时,当处理请求超出一定阈值时,及时告警,做好扩容,优化等其他准备。

当然依据业务模型的不同,还有很多预防的措施,依然是前述做到知底,才能够找出适合自身的方法。

5 过载保护

处理过载的方法有许多,适用于不同的业务场景,并无绝对的最优方案,合适的才是最好的,但能匹配上 “合适” 一词,是对系统整体和经验的一个考验。下面介绍一些常用的处理方案以及我们是如何做的:

请求量阈值控制

在系统部署上线之前,预估好系统的处理能力,限定最大同时能够处理的请求量、流量或者链接数。当请求量快接近于最大处理能力时,则告警,超过范围,则触发拒绝请求机制。由此可见对于阈值的设置是一个很关键的环节,阈值过高,依然可能导致过载,阈值过低,则又导致负载上不去。阈值的设置也会是一个不断调优的过程。该方法的优点和缺陷都很明显。

优点:识别和处理简单;

缺点:阈值的设定需要一定的经验,会有一定的难度,同时如果处理能力发生变化时,阈值就很难动态发生变化。

监控系统资源

服务器监控 CPU,内存等资源的使用情况,设定阈值,超出阈值,则可以认为过载,从而触发拒绝请求机制。

优点:使用动态的资源数据,从相对根本的原因上识别过载,而无需过多关心具体的业务处理;

缺点:一是处理相对复杂;二是在某些场景下,资源数据的耗尽并不意味着出现过载的情况。例如服务开了较大的内存池,看起来内存资源耗尽了,实际上负载是足够的,又如现在都是多核服务器跑着多进程或者多线程的服务,单一的 CPU 耗尽也不能够代表服务就出现过载,但又可能产生过载,这就和具体业务有关;三是在某些场景下,出现过载的情况,也不一定会耗尽资源,例如当前所有的服务都在等待之中(可能是后端的回复或者其他),同样也不会对 CPU、内存、io、网络等资源造成影响,但依然进入了过载。总体来说该方式适合的场景相对会简单点。

检测请求到达时间

依据请求处理的时延来判断是否过载。记录请求到达的时间戳,和处理请求结束的时间戳,得到请求到达自身服务器处理的时延,超出阈值,则可判定为超时失效,可以直接丢弃。使用独立模块读取系统缓冲区中数据,打上时间戳,存入消息缓冲区,在处理时,超过一定时延的请求,则拒绝处理,因为可以认为即使处理了也是无用的。从中可以看出时间戳很关键(为啥会单独提出这个问题,因为在后续的方案设计中,时间戳依然是解决过载问题的关键点,此处先卖个关子)。

A、时间戳如果使用本地读取时刻调用系统的时间函数获取,就没有考虑消息包到达系统缓冲区的时间,因此是万万不能这样做。

B、到可以通过 ioctl 调用 SIOCGSTAMP 的接口,获得时间戳,但这会加大系统开销,原因是每次 recv 完,都需要重新设置一下 ioctl 一次。并且不是线程安全的。

C、使用 socket 选项 SO_TIMESTAMP,通过带外数据获取到数据到达系统缓冲区的时间。

其处理方式如下图所示:

通过这种方式已经能够很好地解决负载问题,通过如此,并不需要设置过于繁琐的配置或者去识别过载的问题,目前此方法在 SPP 的框架中在使用。个人觉得可能存在的一些问题在于:

1、完全使用时间戳过期的方式来判断,并不一定适合所有场景,假设处理耗时过长,而在缓冲区中也呆了较长时间,但请求量并不大,服务器未过载,在处理一些需要强写入的情况下,单靠该机制也会稍许欠妥。但如果加入一些协议上层机制,告诉该消息务必执行,也是可避免的。

2、在出现过载的情况之下,很可能会导致整体的服务都会产生一个固定的延时,因为每次抛弃到可执行的范围内,至少会有一个超时时间范围内的延时,如果是较长的服务链的话,最前面的等待服务很可能会出现超时,因此其延时的设置相对也很困难,过小就太过灵敏,过大就会出现刚所述的问题。

3、该方式只是管理了到达本服务器缓冲区之后的问题,并没有考虑整条服务链上的延时,很可能到达本服务器缓冲区时,就已经过期了,并且有可能这些数据在对端缓冲区已经产生了堆积,但到本端,并不会判断其过期。

4、剩下还有一些内容可以做更多优化:另外 SO_TIMESTAMP 使用的是系统时间,会受系统时间修改的影响,但这个问题也不大,因为即使修改了,影响的只是本次系统缓冲区的数据。其他可以考虑业务的轻重程度,做按服务来丢弃。

本文由腾讯 WeTest 团队提供,更多资讯可直接戳链接查看:http://wetest.qq.com/lab/

微信号:TencentWeTest

java系统过载保护_过载保护之常见过载处理相关推荐

  1. java设计缺陷_多个常见代码设计缺陷

    0.前言 在软件设计开发中,代码的设计都体现在:子系统与子系统.模块与模块.函数与函数之间的关系,设计越糟糕的软件,维护成本越高,质量也往往难以达标和称赞. 好的设计必定是:层次关系简洁.清晰.易维护 ...

  2. 苹果4s有java系统版本_网友把iPhone4S/5降回iOS6系统后,好用的哭了!

    最近苹果对老iPhone的降频事件已经成为新年科技圈最火的事件了,目前依然还在发酵,最后到底会如何收场,可能连苹果自己心里都没有数吧.不过,除了老iPhone的降频门事件,最近还发生了一件事,更让果粉 ...

  3. java log 断点_项目中常见的log日志调用

    第一种用法:引用org.apache.commons.logging.Log. import org.apache.commons.logging.Log; import org.apache.com ...

  4. java视频接口_视频源常见接口介绍

    在录制和播放中,要通过接口实现文件的传输,下面介绍常用接口. [AV IN/OUT/PHONES]:这是一个多功能的插孔,在菜单里可以设置其功能.当设置为[IN/OUT]时,此插孔可以输入和输出音频以 ...

  5. java编写桌球游戏素材小球图片_你学不好Java还是有原因的!拿走这套Java系统教程,自学必备...

    很多同学都遇到过一种情况:就是无论自己怎么学Java,到头来发现学的都是皮毛,当真正去用python去做一个项目的时候,脑袋里面一片空白.完全不知道从何做起! 那是你没有系统的学过一次Java,现在的 ...

  6. java 用户名不为空_[Java教程]【关于JavaScript】常见表单用户名、密码不能为空

    [Java教程][关于JavaScript]常见表单用户名.密码不能为空 0 2015-05-31 12:00:14 在论坛等系统的用户注册功能中,如果用户忘记填写必填信息,如用户名.密码等,浏览器会 ...

  7. ## 大一java课程设计_航班查询系统(我是小白)

    大一java课程设计_航班查询系统(我是小白) 备注:第一个java程序有借鉴别人的成分,因为忘了在哪个大佬上面借鉴的,所以在此备注,如有侵权,请联系删除,(仅用于学习使用,并未想盈利) 框体介绍 一 ...

  8. java 摄像头 win7_Win7系统下JAVA摄像头调用_实例代码介绍

    Win7系统下JAVA摄像头调用_实例代码介绍.由于要搞个人脸识别登录(JAVACV),百度谷歌了一下午,找了网上简单的样例代码来试,可是老是调试不过,出现CaptureDeviceManager.g ...

  9. java 系统自动检测_如何在Java中检测OS(操作系统)名称?

    java 系统自动检测 To detect the OS (operating system) name in Java, we use the getProperties() method, whi ...

  10. java系统项目分为哪五大层次?控制层_业务_一个项目中说系统分为表现层、控制层、逻辑层、DAO层和最终数据库五层架构-转...

    表现层就是看到的东西,比如你现在看到的当前页面 控制层就将你的请求从页面传到后台代码 逻辑层就是处理你的请求的代码 DAO层就是将数据存到数据库中的代码 数据库就是数据库了,存东西用的 ,DAO层就是 ...

最新文章

  1. 全员远程办公,半年入 1 亿美元:GitHub 的最大竞争对手上市了!
  2. Linux Kernel and Android 休眠与唤醒(中文版)
  3. 牛客16596 计算系数(排列组合)
  4. Bella Email邮件发送模板
  5. canal kafka 环境搭建
  6. leetcode1576 (2022.1.5)
  7. java netty能做什么_开发:Netty快速入门,一看就懂!
  8. ubuntu中显示本机的gpu_Ubuntu下实时查看Nvidia显卡显存占用情况和GPU温度
  9. GitHub 告急!黑客威胁程序员不交钱就删库!
  10. [Python] set()函数 创建一个无序不重复元素集
  11. 类垂直站点插件实现与分享
  12. [转] 电子技术*笔记4【2013-03】
  13. 计算机定时关机命令,定时关机命令,小编教你怎么使用命令行定时关机
  14. iPhone12mini 参数配置曝光
  15. Linear Regression Logistic Regression
  16. Hadoop常用命令参数介绍
  17. 做一个简单的java小游戏--单机版五子棋
  18. STM32F0/F1/F2/F3/F4/F7编程数据中英文手册(所有型号中文参考手册)
  19. QT学习:字体对话框
  20. Type 3 fonts error for pdf files

热门文章

  1. 微云存储空间多大_qq微云内存多大
  2. java对象的哈希值_对象的哈希值
  3. CNN网络实现垃圾分类
  4. [MATLABSIMULINK] 如何提取并处理Simscape Power System 中powergui的谐波分析数据
  5. VBA单元格、工作表、工作簿
  6. 搭建一个 nodejs 脚手架
  7. Halcon原理:auto_threshold算子
  8. Ruby File.open 方法打开文件和File.new 方法打开文件的差别
  9. 编译原理 实验二 递归下降语法分析程序
  10. Linux--DNS域名解析