负载
模拟用户操作 对服务器造成压力 的过程。
性能测试(performance Testing)
模拟用户负载 来测试系统在负载情况下 系统的响应时间、吞吐量等指标是否满足性能要求。
目的:是否满足性能需求
性能测试的目的
1、系统最佳用户数(系统响应时间不受影响时可接受的最大用户数)
2、系统最大用户数(系统响应时间延迟,系统响应失败时的最大用户数)
3、找出系统瓶颈
4、稳定性测试(较高数量的用户长时间访问系统,系统一直能有效响应,并没有明显的效应时长起伏或者死机)
性能分析的主要目的
是别出工作负荷中哪些组件是当前提高性能和整体吞吐量的瓶颈,以及当工作负荷已经导致硬件能力饱和时,哪些硬件配置的改进会提高工作负荷的吞吐率和性能。
监控系统各类资源使用情况的目的
使系统所有资源得以最大程度的发挥作用,以最低廉的成本达到各应用的最佳性能,实现资源最大利用。
负载测试(load Testing)
在满足性能指标、在一定软硬件环境下, 通过不断加大负载来确定能承受的最大用户数。
目的:获取最大用户数
负载测试是性能测试的一种手段
稳定性测试(Endurance Testing)
在满足性能指标、在一定软硬件环境下,长时间运行一定的负载,是否运行稳定。一般会在满足性能要求的情况下加大1.5到2倍的负载量进行测试。
目的:测试系统稳定性
压力/强度测试
在一定软硬件环境下,通过高负载的手段来使服务器资源处于极限状态,测试系统在极限状态下长时间运行是否稳定,确定是否稳定的指标包括TPS、RT、CPU Using、Mem Using等。
目的:极限压测
配置测试(Configuration Testing)
为了合理的调配资源,提高系统运行效率,通过测试手段来获取、验证、调整配置信息的过程。通过这个过程我们可以收集到不同配置反应出来的不同性能,从而为设备选择、设备配置提供参考。
目的:找出系统最优配置
场景
模拟真实用户的业务处理过程
并发
并发分为狭义和广义。
狭义并发指所有人在同一时刻做同一件事情或操作,目的是测试数据库或者程序对并发操作的处理。多适应于性能测试、负载测试、压力测试、稳定性测试。
广义并发指多个用户对系统发出不同的请求和操作,多适用于混合场景和稳定性测试场景。
TPS
每秒完成的事务数,通常指每秒成功完成的事务数。一个事务是一个业务度量单位。有时一个事务会包含多个子操作。
RT/ART
响应时间/平均响应时间,指一个事务花费多长时间
PV
平均每秒有多少用户访问页面
Vuser
虚拟用户
思考时间
模拟正式用户在实际操作时的停顿间隔时间。在脚本中体现为脚本中两个请求语句之间的间隔时间
标准差
标准是多次测试统计出来的。标准差越小说明系统越稳定。
容易造成性能问题的编码要点
1、正则表达式非常消耗CPU
2、避免引用类型和基础类型之间无谓的拆装箱操作,应尽量保持一致,太频繁会严重消耗性能
3、输出异常日志时,如果堆栈信息明确,可取消输出详细堆栈,异常堆栈的构造是有成本的
https://zhuanlan.zhihu.com/p/95148740
性能测试硬关注点
1、cup占比、内存使用空间、网卡流量、磁盘空间(4台服务器的都要监控)
2、cpu
先了解CPU的情况,如逻辑处理器、处理器型号、主频率、cache大小、是否支持超线程技术,然后关注cpu的使用率,当cpu的使用率高于80%时,系统应报警。通常我们要结合系统附带的一些监控分析工具,检查相关的系统日志、web服务器应用日志、DB日志等,并结合一些辅助命令分析系统CPU为啥很高,以及后续的解决优化方式等。
3、网络
需考虑网络是否可达、防火墙是否开启、端口的访问、宽带是否被限制、路由的寻址、网络的时延等问题。
4、I/O
需考虑IO的TPS\平均I/O数据、平均队列长度、平均服务时间、平均等待时间、IO利用率
性能测试软关注点
请求时间、出错率、TPS、响应状态
性能分析公式汇总
1、用户响应时间 = 服务器响应时间 + 网络时间
服务器响应时间指从服务器接收请求到该请求的响应处理完毕,并把对应的数据全部发往客户端的响应时间。
客户端的响应时间很明显是网络响应时间+ 服务器的响应时间,网络延迟、拥塞都可能导致整个用户体验的响应时间很慢
2、CPU使用率 = 1-空闲时间/总CPU时间
除了空闲时间外的其他时间占用cpu时间的百分比
3、CPU负载 = (一段时间内正在使用CPU的任务数 + 等待使用CPU的任务数+等待I/O访问的进程数)/一段时间
性能测试常规通过标准
1、性能测试通过标准包括服务端性能、前端性能、和用户性能
2、服务端性能
- 1.超时概率 小于0.5%通过
- 2.错误率小于0.5%通过
- 3.TPS大于期待高峰值通过
- 4.CUP利用率小于75%通过
- 5.响应时间小于期望值通过
- 6.平均每核CPU的Load小于1
- 7.JVM内存使用率小于80%通过
- 8.Full GC平均大于半小时1次通过
3、前端性能
YSlow评定为C级或者以上的为通过。
什么时候压测
1、新开发接口
2、服务迁移
3、容错演练
压测如何设置最大并发数
设置线程数100个,Ramp-Up10s,即10秒内启动100个线程,1秒启动10个线程。不限制循环次数,调度器持续时间设置300s
测试方案
5分钟内启动100个线程循环执行,设置最大循环次数9999,根据实际使用情况配置接口配比
top
1、top类似于win系统的任务管理器工具,能显示系统中各个进程的资源占有情况。
https://www.cnblogs.com/ftl1012/p/top.html
常用 top -c
CPU(s):
显示的是当前cpu平均值,若想看每个物理CPU的使用情况,可按下键盘1
%id是统计空闲CPU利用率的,CPU的总使用率用1-%id获得
如果wa%过高(等待输入输出的CPU百分比)需要考虑IO是否有性能瓶颈,可用iostat、sar等命令进行分析
建议每个CPU内核的当前活跃进程数<0.8
swap:
交换分区,类似于虚拟内存,就是当内存不足时,把一部分硬件空间虚拟成内存来使用,从而解决内存容量不足的情况。当swap的user项值在不断变化时,说明内核在不断的进行内存和swap的数据交换,这是真正的内存不够用了
mem
中used是指系统内核控制的内存数,free是内核还未纳入其管控范围的数量。 used的内存不一定的都在使用,还包括过去使用过的现在可以被重复利用的内存,内核并不会把这些可被重复使用的内存交还到free中,所以linux上free内存会越来越少,不必担心
进程实际使用的内存查看RES那列的信息
TIME+ 表示的是进程使用CPU时间的总计,不是进程存活时间,单位是1/100秒
uptime
监控系统过去负载使用uptime命令
uptime可以查看linux的系统负载信息以及当前有多少人登录系统
使用w命令可清晰的看到当前的登录人
1、uptime的时间越长,说明系统越稳定。通过观察系统系统最近一段时间有无重启,可以看出系统是否稳定
2、平均负载是特定时间间隔内运行队列中的平均进程数。
建议每个CPU内核的当前活动进程数<=0.8,
大于1小于等于2时,如果其他资源都正常,系统的性能也可以接受
但是任务数大于5时,系统性能就有问题了
3、从平均负载的三个值可以看出系统负载的趋势
free
用来监控系统内存
物理内存总数:mem_total = mem_used + mem_free
实际使用的物理内存数:-buffers/cache = used-buffers-cache
实际可用的物理内存数:+buffers/cache = free + buffers + cache
交换分区对应的内存总数:swap_total = swap_used + swap_free
-/+ buffers/cache 是不考虑缓存占用的值,所以如果 -/+ buffers/cache: free 的值很小,那么 Linux 的的可用内存就是真的小了,此时要引起注意。
buffer:在内存中还没有被写入到磁盘的内存占用。
cache:已经从磁盘读出到内存的数据。
-/+ buffers/cache 是不考虑缓存占用的值,所以如果 -/+ buffers/cache: free 的值很小,那么 Linux 的的可用内存就是真的小了,此时要引起注意。
buffer:在内存中还没有被写入到磁盘的内存占用。
cache:已经从磁盘读出到内存的数据。
buffer和cache的作用是缩短I/O系统调用时间,buffer和cache会占用一定的物理内存,但是当系统需要内存时,这些内存会立马释放出来。buffer/cache清理是把物理数据同步到磁盘。为保证清理buffer/cache的时候数据不丢失,需先执行sync命令
sar
- 若 %iowait 的值过高,表示硬盘存在I/O瓶颈
- 若 %idle 的值高但系统响应慢时,有可能是 CPU 等待分配内存,此时应加大内存容量
- 若 %idle 的值持续低于1,则系统的 CPU 处理能力相对较低,表明系统中最需要解决的资源是 CPU 。
hprof
hprof能够展示CPU使用率,统计堆内存使用情况
性能分析方式
自底向上:通过监控硬件及操作系统性能指标来分析性能问题
自顶向下:通过生成负载来观察被测试的系统性能,比如响应时间、吞吐量
CPU分析汇总
1、了解cpu的情况
2、linux系统使用命令
top\free\uptime\sar
3、java程序使用命令
Jvm自动命令 jstat\jmap\Jvisualvm\JConsole\jps\jstack
4、MYsqlcpu占用情况分析 工具及命令
Spotlight\Monyog\
cpu占用过高排查思路
https://zhuanlan.zhihu.com/p/69342660
使用top命令查看占用cpu的进程pid
使用ps -ef 或者jps -l 得知是哪个程序出错
使用ps -mp 进程 -o THREAD,tid,time 定位到具体的线程或代码
或者top -Hp pid 查看进程中占用cpu过高的线程id tid
使用jstack 进程id 找到报错信息
或者使用jstack pid | grep tid 的十六进制 -A 30查看堆栈信息定位
导出jstack和内存信息,然后重启系统,尽快保证系统的可用性
内存溢出排查思路
一般内存溢出往往是因为大对象不能回收造成的,这些大对象往往就是集合对象。寻找大对象、分析内存溢出需要分析堆信息。时使用jmap -dump:format=b,file=d:\heap.hprof [pid] 命令将堆内存信息倒到.hprof文件中,然后使用Jvisualvm 工具或者jhat命令查看实例化的对象数目,如果分组统计排序一下就知道哪个对象实例化的多,然后分析对象的引用就可以找到是谁在实例化此对象了。
内存不足的表现
vmstat
free memory急剧减少,回收buffer和cacher也无济于事,大量使用交换分区(swpd),页面交换(swap)频繁,读写磁盘数量(io)增多,缺页中断(in)增多,上下文切换(cs)次数增多,等待IO的进程数(b)增多,大量CPU时间用于等待IO(wa)
tomcat监控
通过对容器的监控可以了解到java程序的运行状况,对容器的监控实际上是对JVM的监控。
JVM的监控分析工具有很多,如Jconsole,Jprofiler,Prode等
JVM的监控分为两类,一是堆内存,二是线程;从堆内存可以分析大对象与内存溢出等问题;从线程状态及线程信息分析出低效程序,解决CPU资源占有问题
安装并修改prode配置后,重启tomcat就可查看java程序运行情况
JVM堆内存布局
https://blog.csdn.net/shiyong1949/article/details/52585256/
堆内存 = 年轻代 + 年老代 + 永久代
年轻代 = Eden区 + 两个Survivor区(From 和To)
命令jstat -gc pid 250 4 打印信息的字段中
S0C S1C 代表Survivor0/1区容量
S0U S1U 代表 Survivor0/1区使用量
EC 代表Eden区容量 EU代表Eden区使用量
OC代表年老代容量 OU代表年老代使用量
PC代表永久代容量 PU代表永久代使用量
YGC代表年轻代GC次数
YGT代表年轻代GC耗时
FGC代表 Full GC次数
FGCT代表 Full GC耗时
GCT 代表GC总耗时
线程池监控
current_thread_count 代表当前线程池中ready状态的线程数
current_thread_busy 代表当前线程池中活动状态的线程数
max_threads 代表最大线程池数量
关注点:current_thread_count 或者current_thread_busy 接近max_threads时,需要加大max_threads数量;如果服务器硬件支撑不了更多的线程数,就需要更强的硬件或者做集群来分担负载。
jvm old区域占用过高排查思路
top查看占用cpu高的进程
jstat -gcutil pid 时间间隔 查看gc状况
jmap -dump:format=b,file=name.dump pid 导出dump文件
用JvisualVM分析dump文件
jps
作用: 主要返回当前系统中的java进程号
命令: jps [options] [hostid]
说明:
1、不指定hostid就默认是当前主机
2、命令行参数 -m : 输入传入main方法的参数
3、命令行参数 -l : 输出main类或者jar的全名
机器上有多个jvm进程时如何确定自己访问的服务对应哪个JAVA进程?
在访问服务器时URL
jstack
作用:主要用来查看某个java进程内的线程堆栈信息
命令:jstack [option] pid
jstack [option] executable core
jstack [option] [[email protected]]remote-hostname-or-ip
说明:
1、-l 打印额外的锁信息(在发生死锁时可使用jstack -l pid来观察锁持有情况)
2、-m 不仅会输出java堆栈信息,还会输出c/c++堆栈信息
3、-v 返回JVM参数,比如堆大小,此命令方便我们查看jvm大小
jstack可以定位到线程堆栈,跟进堆栈信息可以定位到具体代码,在jvm调优中使用非常多。常见操作:找出某个java进程中最耗费cpu的java线程并定位堆栈信息
jmap
作用:主要用来查看堆(Heap)内存使用状况
命令:
jmap [option] pid
jmap [option] executable core
jmap [option] [[email protected]]remote-hostname-or-ip
典型获取方法:用jmap 把进程内存使用情况dump到文件中,再用jhat分析查看
jmap -dump:format=b,file=/tmp/dump.dat 21711
jhat -port 9998 /tmp/dump.dat
jmap -permstat pid //打印进程的类加载器和类加载器加载的持久对象信息输出:类加载器名称、对象是否存活、对象地址、父类加载器、已加载的类大小等信息。
jmap -heap pid 查看进程堆内存使用情况,包括使用的GC算法、堆配置参数、堆内存使用情况。
jmap -histo[:live] pid 查看堆内存中的对象书面、大小统计直方图,带上live则只统计活对象。
jstat
作用:JVM统计监控工具
命令:jstat [ generalOption | outputOptions vmid [interval[s|ms] [count]] ]
vmid是java虚拟机ID,在LINUX/UNIX系统上一般是进程ID,interval是采样时间间隔。count是采样数目。比如输出GC信息 jstat -gc 进程id 250 4
generalOption 代表选项,常用选项有以下几项:
class:用于查看类加载情况的统计
compiler:用于查看HotSpot中即时编译器编译情况的统计
gc : jvm中堆的垃圾收集情况的统计
gccapacity: 用于查看新生代、老生代和持久代的存储容量情况
gccause:最后一次及当前正在发生垃圾收集的原因
gcnew:查看新生代垃圾收集的情况
gcnewcapacity:查看新生代的存储容量情况
gcold:查看老生代及持久代垃圾收集的情况
gcoldcapacity:查看老生代的容量
gcpermcapacity:查看持久代的容量
gcutil:gc统计
outputOptions 代表输出格式
-h5 表示每5行显示一次表头
JVM调优的重点
jvm full gc 会暂停用户响应,也就是不处理用户请求,等待Full gc 完成后响应用户请求,这个等待时间过大会影响用户体验
tomcat瓶颈
一个Tomcat可以启动200个线程。9台服务器是1800个线程
mysql瓶颈
一个数据库连接池可以创建20个连接,9台服务器一共180个连接
性能调优常用手段
(1)空间换时间,内存、缓存就是典型的空间换时间。利用内存缓存从磁盘上取出的数据,CPU请求直接从内存中获取数据,比从磁盘中读取数据更快。
(2)时间换空间,切分数据分批次处理,用更少的空间完成任务处理。上传大文件时常用这种方式。
(3)分而治之,把任务切块,分开执行,也方便并行执行来提高效率。
(4)异步处理,业务链路上有的任务时间消耗较长,可以拆分业务,减少阻塞影响。常见的异步处理机制有MQ(消息队列)。
(5) 并行,多个进程或者线程同时处理业务,缩短业务处理时间。
(6)离用户更近一些,比如CDN技术,把用户请求的静态资源
放在离用户最近的地方
(7)一切可扩展,业务模块化、服务化,良好的水平扩展能力
压测环境搭建
控制机
管理远程负载机 指挥远程负载机运行任务并收集远程负载机的测试结果。也可以参与脚本的运行。
负载机
向被测应用服务器发起负载。负载机需先启动一个客户端程序Agent,这样控制器才能管理负载机。
1、远程负载机首先启动Agent程序,待控制机链接;
2、控制机链接上远程负载机;
3、负载机发送指令启动线程;
4、负载机运行脚本回传状态;
5、控制器收集结果并显示。