今天接着来学习下性能知识,本来是应该先学习一下LR的用法的,不过听完云层大大的课之后,我感觉工具没有这一篇来的重要,我们知道性能有三大步骤:负载->监控->调优,但是在这个之前我们首先要搞懂需求,需求错了,后面的结果也都废了,需求就是方向,因此需求是非常重要的。
这里再强调说明下性能测试,性能测试是为了验证在一定环境下系统满足性能需求的测试,主要是验证性能指标(响应时间、吞吐量、资源利用率)。这里最难的就是很少有人能想明白需求。
我在这里先问下,大家在做性能的时候有没有碰到这样的问题,我是在工作的项目都是经常碰到的,我在华为做性能测试的时候,开发那边的架构师要求我们做系统性能测试,我当时说做多少?他说我们的系统是面向华为的人员,华为员工有十几万正式员工(这里就相当于软件的注册用户为10+万人),那么就让我直接开始测试了。当时的我是一脸懵逼的,我说那么这么多用户,那么在线用户是多少?并发操作的用户数又是多少呢?架构师也一脸茫然,那么在此刻我们想一想,我们碰到的很多项目是不是都是这样?我们反过来想一下,当初设计的时候就没考虑性能,那么我们又怎么能知道这个系统的性能指标呢?就好像你从来都没跑过步,那我又怎么来定你100米要在几秒之内呢?
那么是不是又没法做了呢?不是,我们不能通过已设计好的的性能指标去看系统是否满足性能,但是我们能通过负载去测试系统的各个模块能支持的最大并发数,通过测试反馈结果看一下最大并发用户数是否能满足模块业务需求,如果不能则通过增加机器或者其他优化来提高模块的处理能力。(这里有点类似敏捷里面的流动->反馈),这里要注意一下,什么是最大并发数,我之前应该也提过,在下面这张图里面,最大的并发数可以理解为,你用户再增加但是TPS已经上不去了,此时也就是系统的最大处理能力。
那么这里就开始谈到性能需求问题了,那么性能需求我们要怎么做呢?
- 首先跟客户交流:尽量的明确响应时间,处理能力,资源利用率,负载量几大指标;
- 当然第一点我们一般是很难确定指标的,客户一般也不怎么懂,所以我们一般会去看线上监控包括各个模块的日志记录,通过历史数据去查看每个模块时间段最大峰值访问量,这个当然需要线上有系统监控,通过不同模块的点击量我们就可以推算出负载,然后设计负载场景(这个应该包括最大的点击量、最大带宽、用户数),然后通过历史的最该访问量进行性能测试,通过后可以大致判断性能满足初步需求。监控的历史数据最好能够通过referer记录用户的业务操作习惯,这样我们就能知道每个业务流程的百分比,这样我们就能通过几个方法去模拟用户请求,一个是用run logic,一个是通过C语言rand百分比,最后是用controller通过多个脚本不同百分比用户混合场景进行测试。
- 当日志也不能完全满足时我们还需要参考同类产品的性能测试。
- 最后实在不行我们还可以根据经典的80/20原则去做。(一般不用,可以通过该原则说服用户)
那么这里再提一点,假设用户数有几万人呢?我们去模拟是不是很困难?那么我们又如何去做呢?假设几万人操作系统,那么对于某个模块的TPS是1000,那么我们是不是可以通过减少思考时间和等待的时间来达到这个TPS同时减少用户数呢?(虽然这个连接数没有达到效果,但是现在连接池一般都不是大问题),或者说我们单独测试某个模块呢?你想想看我们要测试一列地铁的载客量,我们需要拿一整列地铁吗?我们是不是可以拿一节车厢就行了呢?
当然,客户虽然不懂得性能的目标,但是我们可以引导客户明确性能测试目标,这个才是解决需求的根本。
通过性能需求的初步了解后,我们应该要知道以下几点:
- 知道测什么?(测试目的是啥?)
- 知道被测对象是什么?(被测对象的架构->分析系统业务流程实现架构)
- 知道被测对象以后会被怎么用?(多少负载跑怎样的业务场景)
- 知道我应该怎么测?
- 知道我测出来的结果怎么算通过!
总的来讲就是,我们最终要知道在什么配置下,资源占用不超过80%情况下,什么样的接口或者流程业务在多少负载能够获得什么样的响应时间和吞吐量。
了解完后那么就是到了我们性能测试的设计,这里有两个维度,一个是能不能测?可以测之后那么怎么测?
- 能不能测?(从协议、实现的架构、工具及脚本开发去衡量,看是否可以测试)
- 怎么测?(就需要测试计划(一般不用)->方案->测试场景->测试流程->测试数据)
这里就以几个例子来说一下怎么测:
1、下载p2p软件性能该如何测试?
看到这个我们首先要想下,p2p到底是什么?工作原理是什么?是不是我们登录系统后,可以获取在下载这个文件的所有用户,然后系统通过对用户的速度排序,在给与我们映射关系。那么p2p软件是否好以什么来衡量呢?是不是启动要快、加载分析要快、下载速度要快、最后还要资源占用低呢。那么知道了这些之后我们怎么测试呢?这里以测试服务器端为例来说一下,服务端是不是就是下载种子文件,解析,查询所有下载该文件的用户ip,排序用户获取和你最近或者速度最快的节点,然后指派给你,那么你知道这个后,你是不是就能知道应该测试p2p服务器哪些性能?
- 服务器能支持多少用户在线?
- 查询匹配用户的效率(时间有多快和代价有多大)
- 服务器上的对应资源利用率
因为服务器端最主要还是给用户做匹配,最终下载还是用户和用户之间的事情。
2、系统调用PLC机械打点采集,由于采集点众多导致的性能问题?(这个可以想下微信的步数计数然后发给服务器,服务器进行统计再排序)
其实这个性能问题就相当于众多PLC对系统进行反馈,PLC上发给服务器,确认上发成功即可。那么我们应该怎么测呢?我们是不是模拟多个PLC同时上发数据即可?当然PLC可能会多一个过程,也就是物理信号转化为数字信号的这个过程,然后再对服务器产生请求,那么物理信号怎么转换成数字信号呢?我们是不是可以通过SDK来实现这个模拟物理信号的问题呢?通过LR或者Jmeter去调用即可。
3、手机定位服务软件如何进行性能测试?(大众点评、美团等)
对于定位来讲,是不是就是通过GPS找到手机定位的x、y的坐标,然后发送该坐标到服务器,查询在x、y范围内的记录的过程,而且基本上店面的坐标都是表的记录,所以主要都是查询的问题(这个如果用redis做缓存机制的话可能性能问题更少)。
4、上传下载的性能怎么测试?
其实上传下载更多的是带宽占用多,hit很少的业务(大多数都是,因此也不太需要性能测试),对于特殊的平台可能需要,像快手、抖音这些需要,其实这个下载或者上传相当于一个页面一样,跟我们模拟并发请求是一样的道理。
从这几个案例来看怎么测,总体思路应该是这样的,首先我们先看是c/s还是b/s还是单机,然后解决负载源的问题,解决负载源的关键就是如何重写客户端(通过LR或者Jmeter去录制修改脚本模拟也可以自己写程序然后通过多进程调用模拟并发),最后跟踪记录客户端所产生负载的对应指标。
所以对于
- 负载工具->一般都是实现协议模拟和处理协议的数据结构,模拟并发用户
- 监控工具->定位系统资源和定位具体执行细节(能记录到代码调用执行是最好的了)
- 辅助工具->性能数据的生成
在编写测试方案里面我们需要写测试策略,测试策略可以有如下几个步骤:
- 先做单用户负载,看指标是否平稳
- 再做最大处理能力的性能测试
- 按照业务正常负载做负载测试
- 常见业务的交叉混合测试
- 长时间拷机(正常或较高负载)的压力测试
物理环境:
在我们做性能测试的时候,性能测试的环境往往可能就是测试环境,即使自己再搭建多一套也一般与正式环境存在一定的差异,那么这个时候就存在物理环境偏差,那么我们测试的数据又如何推算出线上的环境能支持多大的压力呢?
- 等比缩放(假设线上的应用服务器为2台,数据库服务器为4台,那么我们可以缩小一倍(或者更多),然后再将处理能力两倍即可,这种推算虽然不是百分百准确,但还是较为准确的)。
- 那如果不是等比例的呢?假设我们应用服务器前面有个负载均衡,测试环境的应用服务器和数据库都是一台,那么又该如何算呢?此时我们可以通过建模,我们可以将应用服务器变为2台,数据库变为2台,然后通过趋势图来推导,假设线上是4台应用服务器和6台数据库,那么我们可以通过1->2支持的TPS,2->3支持的TPS画一个趋势图,然后推算出线上的压力,当然这个也不一定完全准确,但是比我们之间瞎猜还是有依据很多的。
前面的推算都是基于线上服务器和测试服务器的机器配置都是一样的条件下,只是数量不同而已的推算,那么如果配置不一样那又怎么推算呢?还记得之前说过的tpc和spec的概念吗?
- 首先我们可以在测试环境上评估一下一个TPS要占用多少资源,然后和资源的进行换算。
- 得到当前测试环境的硬指标(通过其它工具可以得到CPU、内存、磁盘读写的性能),然后再跟线上的硬指标进行比例换算,得到处理能力,
这里举个例子,假设一个TPS占用测试环境cpu为1%,线上环境的CPU的处理能力是测试环境CPU的2.5倍,那么我们是不是就能大致推导出一个TPS占用线上环境CPU大致为(1/2.5)%也就是0.4%,虽然有一些偏差,但是比我们直接拍脑袋准备的多吧,而且在一定程度下偏差也是可控的。
除了上面之外,其实我们整个架构还需要满足资源占率平衡的,啥意思呢?假设我们是三层架构,web->app->db,对于我们大多数环境而已其实是1:1:1的,那么我们可以直接知道瓶颈首先会在db上面,假设db使用100%的时候,app应用使用为60%,web为20%,那么实际上我们的比例是1:3:5可能是比较均衡的,这样瓶颈点就不会出现在某一个上面,而且使用率都是差不多的(这个实际上是架构师应该去考虑的,没人做所以只能性能测试的我们做了)。当然如果我们测试的时候发现db的资源已经90%了,但是web和app的都不高实际上也是资源的浪费,如果在这个条件下已经满足了TPS需求了,那么我们可以降低web和app应用服务器的资源。(当然做这些事情是比较麻烦的。。。)
软件环境:
对于软件环境我们就需要知道架构所用到的应用程序,服务的版本及配置,每个配置项对性能的影响有多大?以及监控。用什么监控,怎么监控,配置版本环境都得做基线,因为没有了基准,那么就无法做配置测试和基准测试。
数据环境:
我们在需求中需要明确负载下的数据量,然后构造有效地负载数据(手动、自动都行)。
上面的我们都搞清楚和准备好了之后,我们就可以开始场景设计了,
- 用需求作为参考定义负载(明确了需求之后就可以通过需求所知道的来进行场景测试看是否达标)。
- 用极限来获取数据对比需求(如果之前了解需求不够明确,那么我们可以用basic场景来进行加压,看下系统最大的处理能力,然后反推能支持多少用户看下是否满足需求)。
在我们性能测试的时候,可能对于监控,很多时候日志是很少或者不能满足我们性能监控需求的,我们需要去推进开发自己写监控日志,尤其是某些关键接口的处理速度和响应时间(流控超时和业务监控,从这里就可以知道业务单位时间的成交量)。下面是我们所需要监控的指标:
- CPU使用率
- CPU队列长度
- 可用内存数
- 内存硬错误数(意思是内存不足时将内存数据写入磁盘,避免方法有两种,一种是加内存,另一种是提高IO性能)
- 物理磁盘队列长度
- 物理磁盘读写速度
- 磁盘IOPS
- 数据库Lock数目
- 连接用户数
- 数据库的命中率
当需求、计划方案、环境、负载模式和监控都搞定后,我们跑出来的结果之后就可以开始进行分析和定位性能问题了,不过大家可以想下,我们对问题的分析是不是依赖于我们现有的知识,我们通过自己掌握的知识,对已知事务进行了解,然后在这个基础上对事务进行揣摩然后得到自己的理解。所以现有知识的掌握越多那么可能走得越远,当然即使掌握的知识不多,也应该有一个清晰的分析思路,慢慢的梳理分析进行调优并且积累基础知识,具体的内容下次我们再来探讨吧!