第 7 周总结 + 作业
总结
本周内容是性能测试和操作系统。性能测试恰巧是最近项目上谈论很多的问题,明显还有改进空间,比如我们其实只是测到正常负载,没有达到压力测试的程度,还不知道负载范围和极限。操作系统的部分,远不到本科专业课的程度。RAID部分可能是专业课的超纲内容,好在在老东家EMC有三年经历,对RAID还算理解。
性能测试
性能有两种视角:主观视角和客观视角。主观视角主要是使用者的感受,未必是真实性能,但是是亲历的感受,往往更重要,一般通过各种注意力转移,预加载动画和渐进式交互就能提高性能感受,在系统不能马上改变的情况下,这些手段可以改善主观性能。
客观视角下的性能才是我们真正关心并要改善的目标。之后的性能我们都指客观视角下的性能。性能测试是对系统性能的测量,是性能优化的前提和优化结果的检验和度量。不要对没有经过性能测试的系统做优化,那种优化多半是猜测,结果就是“Premature optimization is the root of all evil”。
测试指标
既然要度量,就需要一些指标。跟devops的其他方面一样,这方面的时间也是众说纷纭,但最著名的还是SRE始作俑者google提出的黄金4指标REST(响应时间,错误率,饱和度,吞吐率)。
响应时间(Latency - Response Time)
发起(接收)请求到请求结束的时间。在不同场景下,可能还会细化到首字节,末字节时间等。响应时间是最直接的性能度量,越短越好。测量位置不同,还可以分位客户端响应时间和服务器端的服务时间。客户端响应时间必然大于等于服务时间,因为还包含通信时延(network latency)。
错误率(Error Rate)
错误响应占所有请求数的比率。需要注意的是,这里错误可能要考虑附载是业务错误码的200返回。当错误率升高时,通常表明系统开始不稳定,如若不采取行动,可能累积到无响应,造成不可用。当然,具体的行为要以测试(观测)结果为准,也有可能过线就崩,完全没有反应时间。需要SRE(运维)积累数据做依据。
饱和度(Saturation)
饱和度就是资源利用率,CPU,memory,network和disk等,用来衡量系统资源的繁忙程度。
吞吐率(Traffic - TPS)
单位时间处理请求数。系统只在一定范围的TPS内可以保持一段时间的稳定,当系统过载后,资源可能很快耗尽,然后系统就会崩溃,失去响应。
TPS = 1000 / (total response time in ms) x 并发请求数量^2 x 并发用户数
测试类型
性能测试有多种类型,但前提是测试平台,测试用例和测试数据与生成环境有可比性,测试结果才有意义。
性能测试
测量系统是否达到设计目标,即验证性能NFR,比如50%RT小于300ms,95%RT小于700,99.99%RT小于800ms,不超过1s。 Peak TPS 300,持续2小时。
测试过程,一般可以分为爬坡,稳定和涌浪三个阶段。此种测试类型,一般要求资源利用率不超过70%。
负载测试
测试系统在不同负载情况下的表现,比如低负载(<10%),正常负载(<60%),中负载(<80%),高负载(>=80%)和超载(>100%)。测量系统资源利用率和稳定性——最长稳定时长(第一次失效时长)。
压力测试
测试系统可以承受的极值和超载耐受度。通过加压,知道系统不能承受——开始大量出错并很快失效或是立刻失去响应。为运维提供告警的指导值。
稳定性测试
度量系统可以稳定运行的范围和容错性,比如系统可以在<80%的负载下,对典型用例(正反),满足NFR至少30小时。
全链路压测
全链路压测是指在特定场景下,将相关链路完整串联,尽可能模拟用户行为,做端到端的压力测试。之前对这个概念有个耳闻,但是简单臆想其含义了。这次看到老师给出的定义,意识到就是我们日常所说的集成性能测试。我们把性能测试分为组件测试和集成测试。组件测试可以在隔离环境(mock下游)中进行,反映的是组件自生的特征。集成测试则要求集成真实下游(全链路)的环境中进行,反映的是整个系统的特征。
优化
性能测试一方面是检验性能,一方面也是为优化提供方向。但是常见错误就是直接优化应用代码。这样做很可能没有找准症结,事倍功半。从机房到应用代码,可以逐步优化。
机房基础设施优化(光纤带宽,CDN,反向代理)
服务器优化(垂直扩展)
操作系统优化(内核参数,驱动,资源调度)
虚拟机优化(驱动,虚拟机参数和架构)
基础组件优化(数据库,消息队列,缓存)
软件架构优化(计算密集,IO密集)
应用软件优化(数据结构算法,高级并发编程,异步,池化,应用框架,参数调优)
操作系统
这部分是涵盖两门本科专业课:计算机体系结构和操作系统。介绍了现代计算机的总线中断缓存体系结构和分时段页式虚拟内存操作系统。讲解了操作系统的进程,线程,竞争条件,临界区,线程安全,锁,阻塞,CAS原语,总线锁,内存锁,公平/非公平锁等概念。并进一步讲解Java的锁,偏向锁,轻量锁,重量锁,重入锁,自旋锁,排他锁,读写锁,信号量,乐观锁,悲观锁等概念。
作业
一
随着并发压力增加,系统响应时间先是由高到低,这是系统预热阶段,不同系统此阶段所需时长也不相同,在此阶段,响应时间高于正常水平。继续加压,响应时间会维持在较低水平。此为压力不足阶段,系统即可响应,反应快。继续加压,响应时间会维持在一个区间。此为正常负载阶段,系统个部分正常运行。这个阶段不同系统对压力承受范围不同,在中度负载下,一般响应时间长时间平稳。继续加压,系统进入高负载,此时响应时间明显增大。继续加压,系统不稳定,甚至失去响应。吞吐量的变化趋势是上升,平稳,然后骤降。系统一开始需要启动,预热,所以随着加压,TPS承上升趋势,之后系统正常工作,TPS平稳。高负载后,TPS开始下降,系统过载后,若失去响应TPS则骤降,若响应错误TPS也可能骤升。
二
代码参见https://github.com/linwumeng/go-http-stress
版权声明: 本文为 InfoQ 作者【林毋梦】的原创文章。
原文链接:【http://xie.infoq.cn/article/b16272dcd2c6b6666e7a31a23】。
本文遵守【CC BY-NC】协议,转载请保留原文出处及本版权声明。
评论