注册 登录  
 加关注
   显示下一条  |  关闭
温馨提示!由于新浪微博认证机制调整,您的新浪微博帐号绑定已过期,请重新绑定!立即重新绑定新浪微博》  |  关闭

网易杭州 QA Team

务实 专注 分享 做有态度的QA

 
 
 
 
 

日志

 
 

分布式系统过载异常测试实践  

来自张翱   2014-03-20 19:00:01|  分类: 性能测试 |举报 |字号 订阅

  下载LOFTER 我的照片书  |

何为过载异常测试

过载,简单地讲就是系统当前所承受的压力超过了自身的处理能力。异常,是指一切非正常的运行状态。回顾诸多项目事故不难发现,当大压力遇上异常,所引发的往往都是触目惊心的血案。

2012年6月29日,供电故障影响了AWS US East Region中约7%的EC2和EBS实例,在电力恢复后的集中恢复过程中,EC2和EBS管理服务过载,同时大量服务器上线触发ELB管理服务的一个未知BUG,并进而导致ELB管理服务过载,整个恢复过程持续数小时。

2014年1月,某应用由于推广活动,特定接口调用量指数级增长,其依赖的后端服务缓存超时,触发大量回调,应用服务器和后端服务器双方互调接口全部超时,连接占满,系统不可用时间接近1小时。

如何有效减少惨案的发生,需要我们提前对某些过载和异常进行模拟测试,我们所说的过载异常测试就是指当系统处于大压力背景下,通过一些手段使系统运行在异常状态时所进行的测试。过载异常测试属于异常测试,也许有人觉得重新搞个名字有点哗众取宠,但其实只是想突显压力在异常测试中的重要性。其所关注的是在持续压力下,系统中某个异常状态的累积效应和连锁反应。如果没有压力或者压力较小,异常状态就有可能被消化而没有积累到某个临界点。 

对系统的预期

在测试之前,需要事先对测试过程中可能出现的系统行为有所预期:

  1. 异常出现后的应用及系统行为,在超出系统处理能力后能否合理拒绝后续的请求,能否继续提供服务,正常情况下系统应该正常处理请求,而不是挂住卡死。
  2. 异常消除后的应用及系统行为,系统能否在短时间内从异常状态中恢复过来。
  3. 整个过程中需要观察各项资源的变化,尤其是连接和句柄是否会出现泄漏等

只有确定了预期行为,后续的测试和分析才会有据可依。

如何模拟压力

大压力是过载异常测试的一个前提,压力最好不是单一的,应该尽量模拟线上的请求模式或者采用真实流量数据,因为系统中的逻辑单元往往存在相互依赖的关系,某些连锁反应需要复杂的逻辑路径来覆盖和触发。脱离线上实际情况的过载异常测试就好像空中楼阁,其借鉴意义会大打折扣。那么,有什么方法模拟线上压力呢?这里可以采用线下模拟和线上引流两种方式产生我们需要的流量。

  • 线下模拟需要对生产环境的请求数据进行分析,抽取出一个近似的模型,包括各种请求类型的比例、并发数、数据传输或流量大小、数据库数据构成和规模等等。其实这项任务本身就是一个大的课题,模型越真实测试效果当然越好。
  • 线上引流则推荐tcpcopy工具,它免去了建立模型的过程,直接实时从线上复制请求,而且对生产环境影响小,但并不是所有线上请求都能在测试环境落地,可能存在一些数据准备和请求适配的问题,总之无法保证所有请求都能在测试环境得到正确响应。两种方式各有优劣,可以根据项目自身情况选择。

如何模拟异常

接下来我们就可以开始模拟异常了,主要从以下几个方面考虑。

资源超限

这里的资源是指广义上的资源,可以是应用服务层面,也可以是操作系统层面:

  1. 应用服务层面的资源主要包括线程池、连接池、有界队列等,这类资源通常是由配置项进行设置的,一般能够通过有限的并发达到其上限;
  2. 操作系统层面的资源主要是CPU、磁盘和内存,可以通过一些工具模拟资源争用,例如使用FIO和Cpulimit等工具可模拟磁盘和CPU资源的争用。

响应变慢

说到响应一般就涉及到多个子系统的同步调用或者说依赖。假设在一个简单的系统中,A调用B,B调用C和D,我们需要覆盖所有使响应变慢的路径。而对于路径上特定节点的响应变慢,如上例中B变慢的情况,又可以分解为B接收A的请求变慢和B返回A的响应变慢两种。

响应变慢主要通过tc和iptables两个工具来模拟,tc主要用于流量限制模拟,iptable用于实现限制连接的建立。

依赖服务的错误或异常

如果所依赖的后端服务因为某种原因出现大量错误或异常,如http请求返回大量5xx响应、rpc调用抛出大量异常等,我们需要关注这些异常是否都能正确处理,需要检查资源有没有回收、连接能不能释放或者关闭,会不会出现内存和连接泄漏。

这种情况可以通过mock服务模拟,在mock服务中设置一个随机数使其有一定概率返回给被测应用错误或异常。如果确实存在某种资源泄漏,运行一段时间后我们的请求将完全失败。

高可用异常

系统中某个服务高可用,当其中部分高可用节点因为某种原因挂掉时,能否保证整个服务可用。高可用又有主从和双主两种形式,需要区别对待。主从情况下,从节点一般不提供服务,只有在主节点挂掉时才会切换到服务状态;双主情况下,所有节点的地位是平等的,请求一般会负载均衡到所有节点。出现节点异常时不同的高可用类型会表现出各自的行为。

我们在模拟节点不可用时主要采用下文中提到的进程挂和主机宕机两种手段。

多副本异常

多副本在分布式存储系统中十分常见,是一种从数据安全角度考虑所做的数据冗余。和高可用中的双主形式比较类似,各副本地位平等,但对读写操作有不同的行为,视具体的系统策略而定。比如在某些系统中,所有副本写操作都正确返回才表示写成功,而只要一个副本读操作成功就表示读成功了,因此副本异常时我们对读写操作的预期也就不同。

模拟副本不可用的场景,同样也是采用进程挂和主机宕机两种手段。

缓存失效

缓存是提高服务响应、提升最终用户体验的重要手段。如果缓存失效了,请求是否能正确到达后端,是否会对后端造成很大影响。

这种情况可以通过限制缓存大小,改变其命中率来模拟。

进程挂

进程挂主要通过kill掉进程来模拟,同时要注意不同的信号会产生不同的实际效果。

主机宕机

主机宕机在物理机环境下可以通过拔掉网线来模拟,但通常这种方式对测试的服务器可行性不高。我们可以通过在虚拟机内启动服务,然后kill掉虚拟机进程来模拟这种情况。

分析的困境

执行完测试,需要对测试结果进行分析。在验证应用服务行为的时候,我们主要通过其输出的日志来分析。当异常发生时,应用日志会被异常堆栈淹没,这些异常信息大部分是合理的,但我们需要从中挖掘出那些不合理的部分,或者说是异常中的异常。这时候人肉检查势必遗漏很多问题,即使借助Linux下的grep、awk等工具,其效率也十分有限,一个日志自动化分析工具才是解决问题的关键。在实践中我们基于Hadoop Hive定制了分析应用日志的工具,收到了不错的效果。

最佳实践

过载异常测试是对系统中异常处理和过载保护的有效性检验,在此总结一下几种实践经验:

  • 服务隔离:服务隔离可以按业务类型和核心程度进行划分。按业务类型隔离,如存储系统中读写业务分离、多媒体处理中图片视频模块分离、同步异步服务分离等等,把不同的业务分隔到不同的处理路径上,保证在某个路径上出现的异常不会波及到其他路径,使影响控制在有限的范围内。 根据业务的核心程度进行隔离,能够在异常情况下保证核心业务继续服务,把非核心业务部分或完全关闭。服务隔离又可以从物理和逻辑上进行具体实施。物理隔离,即把不同业务分隔到不同的磁盘、进程、机器甚至机房里。逻辑隔离,即对提供服务的逻辑单元进行隔离。
  • 设置超时:经实践证明,超时是最简单而行之有效的保护手段。建立TCP连接、数据传输需要设置超时,HTTP客户端发送请求也需要超时。在进行开发时我们应该明确这些超时配置,使其可配,而不是写死或者使用其默认值。超时参数需要根据依赖服务进行合理设置,太大相当于没有超时,过小则会导致过多超时错误,使后端做了无用功。

结语

随着业务的发展,我们的系统经历着用户量和请求量的增长,系统的各种异常处理和过载保护措施能够为这种增长保驾护航吗?让我们一起通过过载异常测试的实践来回答吧。

  评论这张
 
阅读(425)| 评论(0)
推荐 转载

历史上的今天

评论

<#--最新日志,群博日志--> <#--推荐日志--> <#--引用记录--> <#--博主推荐--> <#--随机阅读--> <#--首页推荐--> <#--历史上的今天--> <#--被推荐日志--> <#--上一篇,下一篇--> <#-- 热度 --> <#-- 网易新闻广告 --> <#--右边模块结构--> <#--评论模块结构--> <#--引用模块结构--> <#--博主发起的投票-->
 
 
 
 
 
 
 
 
 
 
 
 
 
 

页脚

网易公司版权所有 ©1997-2016