性能需求分析::
1:需求分析关键字:
- 系统用户:注册此系统的总用户量
- 在线用户:在某段时间内登录且在线的用户
- PV:用户/游客浏览页面的次数一个用户可以浏览多个页面
- UV:登录系统的用户,UV可产生多个PV,:PV指的用户可以浏览多个页面
- 性能测试:测试软件在系统中的运行性能,度量系统与预定义目标的差距
- 负载测试:是性能测试的一种,通过逐步增加系统负载,确定在满足性能指标的情况下,被测系统最大所能承受的负载量
- 压力测试:是性能测试的一种,通过逐步增加系统负载,确定在什么情况下系统失效,测试系统承受压力的极限
- 容量测试:是性能测试的一种,通常和数据库有关,通常提前测试数据库达到某W行后系统的性能
- 稳定性测试:系统在某个长的时间段,不断有压力,查看系统指标是否异常,系统是否会奔溃
2:需求分析指标
- tps:表示每秒服务器处理的事物数/业务数,还有一种叫法叫:每秒系统吞吐量
- 事物成功率:一段时间内成功的请求在总请求数中的占比
- 事物失败率:一段时间内失败的请求在总请求数中的站比
- rt:表示服务器处理每个请求的响应时间,原则2s-5s-8s
- 总并发用户数:同一时间访问系统上的用户总量,这些用户会分布在不同的功能模块上,比如三个用户同时登录系统
- 总并发请求数:同一时间访问系统的用户同时想服务器做出的请求数量,比如上面三个用户登录系统,但是请求了不同模块,一个用户请求了5个那就是15
- 总并发线程数:指压力测试工具用的线程数量
案例
1:案例
2:案例
3:案例
扩展知识
- 网络带宽:一般公司就会买1G的网络带宽,除以8等于125M,查看带宽看在浏览器上面F12查看请求返回的带宽,如果这次请求用了5kb那计算方式就是:125M=125000kb,125000/5=25000那么得出结论,当前这个请求最大并发就是25000并发
- 静态请求,动态请求: 静态请求是,html,js,cs,jpg这种请求,动态请求是java程序,redis/db数据库,静态请求一般不用进行压测,应为一般公司为了提高用户体验,都会在蓝汛购买cdn机器用来上传静态请求的文件,相当于第三方来进行管控
性能需求分析总结:
- 静态资源不压测
- 动态资源需要压测
- tps先分析出,需要介入28原则
- rt和事物错误率与产品或领导人员确认
- 总并发线程数可先用1个线程做基准得出每秒tps,然后逐渐增加来达到总的tps数量
性能测试计划:
- 版本历史
- 相关文档
- 项目背景
- 入口标准(被测系统的架构图)+被测系统的软件配置
- 测试内容(就是测试什么接口)
- 测试场景(单接口)(全链路混合场景)
- 角色和职责
- 测试计划(就是每个场景需要的工作时间)
- 出口标准(就是成功的标准是什么就是最终的效果)
- 风险
中间键监控:
nginx监控:
手工监控
- nginx所在的机器上面安装zabbix-agent客户端
- 编写nginx监控的脚本,此脚本通过nginx服务器发送命令:/usr/bin/curl “http://localhost:80/status/通过grep,awk来进行命令结果的提取,分别有:
方法名 | 方法表示 |
---|---|
accepts | 总共处理了多少个连接 |
handled | 成功创建多少握手 |
requests | 总共处理了多少个请求 |
Reading | 读取到客户端的Header信息数,表示正处于接收请求状态的连接数 |
Writing | 返回给客户端的Header信息数,表示请求已经接收完成,且正处于处理请求或发送响应的过程中的连接数 |
Waiting | 开启keep-alive的情况下,这个值等于active – (reading + writing),意思就是Nginx已处理完正在等候下一次请求指令的驻留连接 |
- 添加nginx监控配置文件,UserParameter=nginx.status[*],/etc/zabbix/zabbix_agentd.d/nginx_status.sh $1此行意思是:接收nginx.status[*]接收*号的参数,并通过参数传入到nginx_status.sh这个脚本中,通过脚本识别出传入的方法
- 配置zabbix_agentd.conf,中配置:lnclude=nginx.conf路径+文件,这样配置后zabbix客户端启动后就可以加载这个配置文件到内存中,直接可以进行访问
- 重启zabbix客户端,zabbix server进行测试,zabbix_get -s ip -p 10050 -k “nginx.status[accepts]”:传入这个方法让脚本执行这个方法,得到zabbix客户端总共处理了多少个请求数
- zabbix服务端,上传该客户端服务器的nginx监控模本,添加后可进行监控客户端机器的nginx
总结: nginx因为模版中有键值会执行脚本方法,系统指标采集是应为zabbix agent底层有对应的代码可以采集
自动化监控:
前提:准备推送机,zabbix-agent机器(安装nginx),zabbix-server机器
1:脚本:
- 把相关文件同步到远程机器上资源目录:/root/tools/shell/nginx/monitor
- 脚本目录:/root/tools/shell/nginx/remote/remote_create_and_zabbix_agent_config/这个脚本功能是:安装zabbix-agent,配置zabbix-agent,启动zabbix-agent
- 手动上传nginx监控的模版
- 手动执行60上面的第一个脚本
监控tomcat jvm:
手工监控
- 前提准备:81,101部署的是tomcat,60作为推送机
- 安装zabbix-agent客户端,及配置上报数据
压力机总结:
上面的案例3进行压力机准备
- 首先把压力机对应的中间件服务器纳入监控
- 代码注释掉防刷机制
- jmeter进行接口准备
- 开始执行压力测试,结果树勾选只输出Error数据
- jmeter参数解释:
参数 | 解释 |
---|---|
Throughput | 吞吐量,表示每秒处理的请求数 |
Std.Dev. | 表示平均方差,值越大表示越不稳定,值越小越稳定,单位毫秒 |
Average | 相应时间平均值,一般这个值很少看,因为不够准确,平均值说明不了问题,单位毫秒 |
Error% | 失败率 |
- 当1个线程没有问题,直接到10个线程,用excel进行记录,吞吐量,平均响应时间,硬件资源
压测总结:
- 所有业务一起压测,此方式符合真是的场景,但是若A接口出现瓶颈,会造成其他接口并发请求数降低,压力上不去
- 理想情况:jmeter请求数随线程组增大,且RT较低,说明服务器处理速度快
- 不理想情况:jmeter请求数随着线程组增大而降低rt慢慢变大,同时请求也会有失败,说明服务器处理能力变弱
压力上不去原因:
- 压力机需要和被测服务器在同一个局域网内(同一个网段:前三个都一样),或者是在公司机器来压测阿里云机器也是不行的
- 压力机或者服务层的网络阻塞(通过发送,接收数据来计算使用的带宽)(查看压力机是否有瓶颈,cpu,内存一般操作不卡就没有问题)
- 服务器端瓶颈(上述都没有问题就是服务器的问题)
监控nginx
作用:负载均衡转发请求的,不参与代码处理,一般企业里面高配的机器部署nginx
指标:
指标 | 对应zabbix |
---|---|
cpu | CPU utilzation下的CPU idle time指标,表示剩余cpu |
内存 | Memory usage下的Available memory指标,表示剩余内存 |
磁盘 | Disk space usage饼状图,红表示总大小,绿表示剩余的磁盘 |
nginx-active | 当前活动的nginx连接 |
nginx-writing | 正在处理的nginx的请求 |
nginx-waiting | 正在排队的nginx的请求 |
监控:
- zabbix监控(硬件资源+服务指标)
- 日志监控(分辨瓶颈源)
通过:查看nginx的log,/usr/local/tengine/logs/access.log查看两个指标,1:upstream_response_time(tomcat到代码底层的时间),2:request_time(整个系统架构层请求时间)用2-1的时间就是nginx所花费的时间 - 负载均衡监控(监控节点状态):http://81.70.195.221/upstream 来查看节点状态
- 并发请求数监控(awk命令)#使用awk 命令进行切割,sort命令进行排序,uniq进行去重显示数量,根据负载均衡策略来定位并发的数量
awk ‘{print $1}’ access.log | sort -n | uniq -c | sort -nr | head -2
经验:
- 活动数=当前线程+zabbix的1个线程=11个线程(如当前线程是10个)
- waiting值如果越来越大,表示客户端建立tcp通道在排队,受阻,则并发请求数下降,rt也会变大
- jmeter rt越来越大或者是报错率越来越高,说明服务器能力变弱,通过日志监控可以分析瓶颈源
- 若是nginx瓶颈,需要通过zabbix监控(硬件+软件服务)来验证,如果硬件使用率高的话那就扩容硬件,反之修改nginx进程数和连接数配置,配置路径:/usr/local/tengine/conf/nginx.conf,
参数:
worker_processes:cpu核数
worker_connections:连接数 - 若不是nginx瓶颈,则据架构继续往后定位
监控代码:
**作用:**业务处理,高配机部署
监控:
- 通过tomcat log下的catalina.out查看用aop监控的代码消耗时间,发现代码耗时较高
aop监控代码如下:
package com.youceedu.spring.code.aspect;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.springframework.context.annotation.EnableAspectJAutoProxy;
import org.springframework.stereotype.Component;
import java.util.Arrays;
/** * @version V1.0 * 注意:本内容仅限于优测教育内部传阅,禁止外泄以及用于其他的商业目 * @Title: ${file_name} * @Package ${package_name} * @Description: 服务性能监控 * @author: chenli * @date: ${date} ${time} */
@Component//将来也会注册到context集合中,代表此类启动的时候就运行了
@Aspect//表示是一个切面类需要配合:@Component使用
@EnableAspectJAutoProxy(proxyTargetClass=true)//标识切面类的开关
public class ServiceMonitorAspect {
//定义常量 常量就是定义完就不改变了
private static final long ALARM_TIME = 10;
@Pointcut("execution(* com.youceedu.spring.code.service.test.*.*(..))")
public void serviceMonitorPointCut(){
}
//被监控的方法执行前和返回结果后执行 次注解标识的方法 ProceedingJoinPoint主要是可以跟踪和记录日志信息
@Around(value = "serviceMonitorPointCut()") //环绕通知必须返回Object
public Object around(ProceedingJoinPoint joinPoint) throws Throwable {
//目标方法运行前后的代码
//运行前----按秒表
long startTime = System.currentTimeMillis();
Object object = joinPoint.proceed();//
//运行后----按秒表
long endTime = System.currentTimeMillis();
//时间差
long diffTime = endTime - startTime;
// if (diffTime>ALARM_TIME){
//此处得到监控的类名UserServiceImpl
String className = joinPoint.getTarget().getClass().toString();
//此处得到监控的方法login
String methodName = joinPoint.getSignature().getName();
//此处得到的方法参数[name=xxx,pwd=xxx]
String args = Arrays.toString(joinPoint.getArgs());
System.out.printf("%s.%s 参数%s,耗时%dms\n",className,methodName,args,diffTime);
// }
return object;
}
}
- jdk安装路径bin目录下jstack可以对程序进行快照截图,查看进行分析,
定位思路:
1:top -H -p 进程pid(查看java程序的所有线程)
目的:查看进程下的线程列表(包含:tomcat线程+code线程+jvm的gc线程)
理想情况:线程S/run,Time短,线程pid从cpu消失快,说明业务代码处理正常比较快
不理想情况:线程一会是S(sleep)一会是run(运行中),Time长,线程pid一直在,一般看前5个,是否一直存在,cpu是否一直标高
2:基于不理想的情况进行线程快照 (注意cpu截取出来的快照都是16进制,需要用在线工具转换为10进制查看线程id)
密令:jstack
作用:对线程进行跟踪
参数:-l(锁的瓶颈),-m(),-F
执行:
A:jstack -l 20768 > /root/20768_l_b.log #20768线程pid,查看锁的瓶颈,并生成一个log存放到某个路径,如果log中有内容的话说明存在锁瓶颈
查看日志:从下往上看,一般就找开发写的代码,waiting to lock <0x00000000ede66408>/parking to wait for 有数据被锁了,http-nio-18080-exec-1″1号线程等待被锁的数据,上面的方法BLOCKED受阻,继续往下找看开始原因出在哪,综合原因:因为某些方法锁了数据,导致无法释放
B:jstack 进程pid #截取cpu内某进程下的所有线程的快照,有可能线程有瓶颈或者没有瓶颈,截取的log为空则表示没有瓶颈,整个截取错误的日志,逐行进行分析
知识:
- 进程和线程:独立程序启动后有一个独立进程,进程拥有独立的内存单元,一个进程至少拥有一个线程,线程和进程共享内存单元
- 优缺点:
线程优点,节省资源,缺点,某线程锁内存影响全体进程
进程优点,进程相互独立,各不影响,缺点,耗内存 - 状态:top命令:R运行,S休眠
- 线程分类:
tomcat线程–http–nio–8080–exec开头
java线程–Thread开头
java gc线程 - 面试题:占用cpu,内存top10的进程
cpu: #ps -aeo pcpu,user,pid,cmd | sort -nr | head -10
内存:#ps aux|head -1;ps aux|grep -v PID|sort -rn -k +4|head
经验:
- 程序代码运行时间长,先查看该机器的硬件资源,硬件资源没有问题表示程序在运行的时候没有拥堵,应该继续往后排查
- 通过1方式:定位问题有时候会不够准确,需要用到2的方式通过jstack监控进行协助,具体查看差额时间,见excel
- 若代码无代码瓶颈,但资源率使用率高,则增配,反之继续据架构向后定位
Jvm监控:
配置路径:tomcat/bin/catalina.sh
jvm原理:
- AG 实例化对象存储在G内存中
- B-F 实例化的数据存储到C中,当C内存满时,gc线程进行回收,程序继续引用给数据移到D内存中,反之清除掉,接着重复此动作操作D,E内存
- 当F内存满时,gc线程进行回收,程序继续引用吧数据给存在F内存中,反之清除掉
- 当老年代已经满了,垃圾回收也回收不掉了,E中的数据往F里面流转,就出现内存溢出现象
jvm回收策略:
- 串行回收:jdk1.5时候的策略,单线程,参数是:-XX:+UseSeriaIGC,遇到大并发的时候会出现垃圾回收不及时
- 并行回收:多线程并行回收(慢的会影响快的)
参数:-XX:UseParallelOIdGC -XX:ParallelGCThreads=cpu - 并发回收:多线程新生代并行,老年代并发回收,参数如下:
–XX:+UseConcMarkSweepGC #并发回收
-XX:ParallelGCThreads=cpu核数 #新生代并行
-XX:ParallelCMSThreads=cpu核数 #老年代并发
jvm监控:
- A:zabbix监控(服务指标)
zabbix选择监控项:Garbage Collector collections per second
指标 | 说明 |
---|---|
gc ParNew number of collections per second | 新生代每秒回收,单位每秒 |
gc ConcurrentMarkSweep number of conllections per second | 老年代每秒回收,单位每秒,0表示没有满过 |
zabbix监控项:Memory Pool CMS OId Gen #监控老年代内存
指标 | 说明 |
---|---|
mp CMS OId Gen max | 老年代配置的总内存大小 |
mp CMS OId Gen used | 老年代一共用了多少内存 |
- B:jdk命令监控
命令:jstat -gcutil 进程pid 1500 #每个1500毫秒监控一次进程信息
参数 | 说明 |
---|---|
S0,S1,E | 表示新生代的三个内存区域,内存使用百分比 |
O | 老年代,内存的使用百分比 |
YGC | 表示新生代的回收次数 |
FGC | 老年代的回收次数 |
YGCT | 回收所用时间,一般用最新的回收时间减去之前的回收时间 |
总结:
- 理想情况下新生代,老年代的值随YGC,FGC下降,整体呈锯齿曲线状,反正不正常
- 不正常情况,一直是一条线,没有下降,有两种定位方式
A:spring aop+jsatck(快照截取)结合监控(查看代码所用时间),若jvm有瓶颈肯定是代码引起的,若程序有问题不一定会影响jvm
B:jmap -dump:file=/xxx/xxx/xxxx.hprof.format=b 进程pid #截取快照,mat工具分析
截取快照后是一个二进制的问件,需要下载到本地后用内存分析工具来打开进行分析,查看前几个占用比较大的是否是程序中写的,开发工具来搜索,如果有用到看用到多少如果不多的话,就表示程序没有问题
面试题:
1:快速评判jvm是否有瓶颈方法
A:正常压测监控jvm变化,看是否正常回收,若都没有问题说明jvm就无问题—看监控
B:因老年代有的内存大,此刻可配置jvm降低(30M,50M)老年代新生代启动后内存大小,再次压测,若内存溢出,因程序无问题,则说明就是jvm的配置过低问题—-修改配置
jvm监控》老年代,正常情况下有gc次数,内存曲线呈锯齿
不正常情况2种原因(1.程序引起 2.jvm配置低)
2:内存溢出和内存泄漏的区别
A:内存溢出是指程序在申请内存时,没有足够的内存空间供其使用, 系统已经不能再分配出你所需要的空间
B:内存泄露是指程序在申请内存后,无法释放已申请的内存空间,一次内存泄露危害可以忽略,但是内存泄漏次数多了就会导致内存溢出
监控redis:
作用:缓存数据,降低db压力
存数据:评论,保单,热点数据,改动较小,sessionid
监控:spring aop + zabbix监控
zabbix监控指标:Stats
指标 | 说明 |
---|---|
Redis.Info[total_connections_received] | 跟redis建立的连接,单位k表示千个 |
Redis.info[total_commands_processed] | 执行的redis命令,k表示千个 |
Redis.info[rejected_connections] | 拒绝连接,拒绝就有问题 |
[connected_slave] | 有几个从库 |
keyspace_hits | 命中次数 |
keyspace_misses | 未命中次数 |
扩展(面试)
- redis有过雪崩的现象吗?:没有出现过,redis挂了,大量key过期
- redis有过穿透的现象吗?:没有出现过,redis挂了,大量key过期
经验:
1:正常情况-cpu负载低,rejected_connections=0,命中率高,降低db压力
2:不正常情况-cpu负载高,rejected_connections值上升,命中率低,解决方法是扩硬件或者定位代码问题
db监控
作用:主库对应写操作,从库对应读操作,读写都是操作磁盘
扩展:
- qps:指的是什么:是对数据库的指标,每秒对数据库的操作(查询量)
- tps:表示对代码,每秒对代码有多少业务操作
监控:
- spring aop监控(代码)+zabbix监控(硬件)
- 慢查询监控:在mysql中vim /etc/my.cnf进行配置,long_query_time=10设置超过多少秒查询时间定义为慢查询,并设置日志打印到:/var/lib/mysql/slow.log,查询出慢查询的sql会在日志中显示,让开发来配合找出问题
指标 | 说明 |
---|---|
MYSQL insert operations per second | 每秒插入数量 |
select | 每秒查询数量 |
delete | 每秒删除数量 |
update | 每秒更新数量 |
Mysql slow queries | 每秒慢查询数量 |
经验:
扩展
- 什么是热备份:进入的数据马上进行备份,保持一致度比较高,主从其实也是热备份,主库一进来从库就备份
- 什么是冷备份:指定时间进行备份,比如每天凌晨备份,一致度比较低
- 数据库配置连接300 jdbc会报错,建立连接太多了
发现性能问题:
1:代码问题:删除渠道识别码的时候,需要查询该渠道识别码关联的保单,当时开发是查询保单的所有数据到内存中,然后再进行遍历判断,当租户数据量小的时候正常可查询遍历,但是有些租户本身数据量比较大,可能有几万条的保单数据,此时程序在运行的时候,内存就暴涨导致内存泄漏
2:发现过redis因为代码配置小的问题导致连接超时,受阻,等待超时等错误,并发量上不去,修改代码中redis的配置
#basic config
redis.pool.maxTotal=300
redis.pool.maxIdle=300
redis.pool.minIdle=300
redis.pool.maxWait=5000
今天的文章YC-性能测试_手机性能测试网站分享到此就结束了,感谢您的阅读。
版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。
如需转载请保留出处:https://bianchenghao.cn/68026.html