QPS指用户发出请求到服务器做出响应成功的次数。
QPS = 总请求数 /(进程总数*请求时间)
注意:
1、微服务也需要计算,每分钟4次默认请求响应。有服务心跳2次注册表、2次发送心跳。
PV(page view)即页面浏览量,通常是衡量一个网络新闻频道或网站甚至一条网络新闻的主要指标。网页浏览数是评价网站流量最常用的指标之一,简称为PV。
原理:每天80%的访问集中在20%的时间里,这20%时间叫做峰值时间。
日PV=QPS * 60 * 60 * 24
峰值QPS = (日PV * 80%) / (60 * 60 * 24 * 20%)
机器:峰值时间每秒QPS / 单台机器的QPS = 需要的机器
每天300w PV 的在单台机器上,这台机器需要多少QPS?
( 3000000 * 0.8 ) / (86400 * 0.2 ) = 139 (QPS)。
那么这台机器需要达到139QPS,因为是峰值。
每秒事务数
统计 1 天内访问某站点的用户数(以 cookie 为依据),一台电脑终端为一个访客。
指 1 天内多少个独立的 IP 浏览了页面,即统计不同的 IP 浏览用户数量。
执行一个请求从开始到最后收到响应数据所花费的总体时间,即从客户端发起请求到收到服务器响应结果的时间。它的数值大小直接反应了系统的快慢。
用户平均请求等待时间(Time per requests)
用户平局请求等待时间 = 总时间 / (总请求数 / 并发用户数)
服务器平均请求等待时间(Time per requests: across all concurrent requests)
服务器平均等待时间 = 总时间 / 总请求数 = 用户平均请求等待时间 / 并发用户数
RT = CPU time + CPU wait time,
并发请求数/连接数,是指系统同时能处理的请求数量,这个也是反应了系统的负载能力。对于CPU,并发数就是处理能力。
并发量 = QPS * 平均响应时间,
并发请求数 = 并发用户数 * 单个用户平均请求数
并发用户数指的是某个时刻同时在线的用户数。一个用户可能同时会产生多个会话,也即多个请求连接数。
吞吐量是指单位时间内系统能处理的请求数量,单位是 reqs/s,体现系统处理请求的能力。
吞吐率是基于并发用户数的。这句话代表了两个含义:a、吞吐率和并发用户数相关;b、不同的并发用户数下,吞吐率一般是不同的。某个并发用户数下单位时间内能处理的最大的请求数,称之为最大吞吐率。
系统的吞吐量(承压能力)与request对CPU的消耗、外部接口、IO等等紧密关联。单个request 对CPU消耗越高,外部系统接口、IO速度越慢,系统吞吐能力越低,反之越高。
系统吞吐量几个重要参数:QPS(TPS)、并发数、响应时间。
吞吐率 =并发请求数/总请求处理时长
比如:在并发用户数为1000时,一共有5000个请求,请求了5分钟,那么每秒钟,服务器可以处理5000/5*60 = 16个请求呢。这就是服务器的吞吐率
1、单线程QPS公式:QPS=1000ms/RT 响应
对同一个系统而言,支持的线程数越多,QPS越高。假设一个RT是80ms,则可以很容易的计算出QPS,QPS = 1000/80 = 12.5
多线程场景,如果把服务端的线程数提升到2,那么整个系统的QPS则为 2*(1000/80) = 25, 可见QPS随着线程的增加而线性增长,但是往往现实并非如此。
2、最佳线程数量
刚好消耗完服务器的瓶颈资源的临界线程数。
最佳线程数量=((线程等待时间+线程cpu时间)/线程cpu时间) cpu数量*
最大QPS = 最佳线程数 * 单线程QPS =(RT/CPU Time * CPU核心数 * CPU利用率)*(QPS/RT) = CPU核心数*CPU利用率/CPU time
注意:
在达到最佳线程数的时候,线程数量继续递增,则QPS不变,而响应时间变长,持续递增线程数量,则QPS开始下降。
每个系统都有其最佳线程数量,但是不同状态下,最佳线程数量是会变化的。瓶颈资源可以是CPU,可以是内存,可以是锁资源,IO资源:超过最佳线程数-导致资源的竞争,超过最佳线程数-响应时间递增。
一台服务器能够支持多少 TCP 并发连接。
一种理论说法是受到端口号范围限制。操作系统上端口号 1024 以下是系统保留的,从 1024-65535 是用户使用的。由于每个 TCP 连接都要占一个端口号,所以我们最多可以有 60000 多个并发连接。
但实际上单机并发连接数肯定要受硬件资源(内存、网卡)、网络资源(带宽)的限制。特别是网卡处理数据的能力,它是最大并发的瓶颈。
服务消费方
服务提供方
网络传输上限是根据你的网络带宽大小决定的。
例如:
100M 带宽的理论传输速率是 12.5MB/ 秒。如果每一秒会产生 10240 次数据传输,平均每个数据包大小是 10KB。那么现在每一秒需要传输:10240 次 / 秒 * 10KB = 100MB/ 秒。那么带宽远远不够
一般来说,系统吞吐量指的是系统的抗压、负载能力,代表一个系统每秒钟能承受的最大用户访问量。而吞吐量通常由qps(tps)、并发数来决定,每个系统对这两个值都有一个相对极限值,只要某一项达到最大值,系统的吞吐量就上不去了。
**以32位Windows系统为例,每一个进程的用户地址空间是2G,假如每个线程栈的大小是128K,最多会有16384 = (2 * 1024 * 1024 / 128)个线程。**实际在XP系统上,大约能启动13000个线程。
一般指的是CPU、内存、I/O读写速率,磁盘空间方面的问题。
一般指的网络带宽,网络波动,延时,丢包等。
一般指的是开发人员新开发出来的应用程序。
例如,程序架构规划不合理,程序本身设计有问题(串行处理、请求的处理线程不够),造成系统在大量用户方位时性能低下而造成的瓶颈。
一般指的是数据库索引,锁,表空间,慢sql,数据量等影响。
比如:超时设置,线程池设置,缓存策略,最大连接数,负载均衡策略等等。
1)用top实时监控cpu使用情况。一般情况下cpu使用率指标是不能超过70%,压测过程中, cpu使用率过高,超过70%以上。
2)分析是use cpu过高还是sys cpu过高,常见的是use cpu使用过高。
3)如果是use cpu使用过高,先把消耗cpu最多的进程找出来(top命令,vmstat),再找到该进程下消耗cpu过高的线程(top -H -p 进程号)或者(ps H -eo user,pid,ppid,tid,time,%cpu,cmd --sort=%cpu命令查找占用cpu高的线程),再把该线程转换成16进制(printf “%x\n” 线程号),再用jstack命令来dump线程栈,看这个线程栈在调用什么东西导致use cpu过高(jstack 进程号 | grep 16进制的线程号)。
4)如果是sy cpu过高,首先查看磁盘繁忙程度、磁盘的队列(iostat、nmon),查看在没有做压测的情况下,sy cpu的使用情况,如果还是较高,则使用strace查看系统内核调用情况,找到系统耗cpu的原因(strace -p 进程号)。
1)稳定性压测一段时间后,LR报错,日志报java.lang.OutOfMemoryError.Java heap space。
2)首先检查JVM配置参数,如果参数设置太小,则需要修改JVM参数,修改xms,xmx,调整堆内存参数,一般是增加堆内存。
3)用jmap -histo pid> test.txt命令dump堆内存使用情况,并且保存到test.txt文件中,查看堆内存排名前20个对象,看是否有自己应用程序的方法,从最高的查起,如果有则检查该方法是什么原因造成堆内存溢出,排查可能的原因。
4)如果前20里没有自己的方法,则用命令:jmap -dump:live,format=b,file=test.dump pid生成dump文件,然后使用MAT进行分析dump下来的堆内存,分析导致内存溢出的方法。
5)如果怀疑是内存泄漏,也可以使用JProfiler连上服务器在开始跑压测,运行一段时间后点击“Mark Current Values”,后续的运行就会显示增量,这时执行一下GC,观察哪个类没有彻底回收,基本就可以判断是这个类导致的内存泄漏。
解决:优化代码,对象使用完毕,需要置成null。
1)稳定性压测一段时间后,LR报错,日志报Java.Lang.StackOverflowError。
2)原因可能是递归没返回,循环调用造成。
3)修改jvm参数,将xss参数改大,增加栈内存。
4)栈溢出一定是做批量操作引起的,减少批处理数据量。
1)稳定性压测一定时间后,日志报Java.Lang.OutOfMenoryError.PermGen Space。
2)这种原因是由于类、方法描述、字段描述、常量池、访问修饰符等一些静态变量太多,将持久代占满导致持久代溢出。
3)修改jvm配置,将XX:MaxPermSize参数调大。尽量减少静态变量。
现象:压测执行一段时间后,日志中有报错信息:java.lang.OutOfMemoryError: unable to create new native thread。
原因:操作系统没有足够的资源来产生这个线程造成的。系统创建线程时,除了要在Java堆中分配内存外,操作系统本身也需要分配资源来创建线程。因此,当线程数量大到一定程度以后,堆中或许还有空间,但是操作系统分配不出资源来了,就出现这个异常了。
解决:
(1)减少堆内存
(2)减少线程数量
(3)如果线程数量不能减少,则减少每个线程的堆栈大小,通过-Xss减小单个线程大小,以便能生产更多的线程。
现象:容量测试压测一段时间后,LR报连接超时错误。
原因:造成这种现象的原因很多,比如带宽不够,中间件线程池不够用,数据库连接池不够,连接数占满等都会造成连接不上而报超时的错误。
分析:
1)使用jstack命令查看Java进程下所有线程的情况(jstack -l 进程号),查询线程栈里有没有block,如果有的话就是线程死锁,找到死锁的线程,分析对应的代码。如果大量线程都是Waiting状态,则需要去关注数据库和中间件,可能会有排队情况。
2)查看TCP连接情况(netstat -an |awk '/tcp/
Unknown macro: {print $6}
'|sort|uniq -c ),用netstat -nat|grep -i “端口”|grepTIME_WAIT|wc -l命令查看TIME_WAIT情况,如果TIME_WAIT的值很大并且一直增加的话,说明tcp不能正常释放,会造成响应时间增加。
现象:容量测试压测一段时间后,LR报连接超时错误。
原因:造成这种现象的原因很多,比如带宽不够,中间件线程池不够用,数据库连接池不够,连接数占满等都会造成连接不上而报超时错误。
分析:查看数据库日志,看有没有死锁的情况:show engine innodb status\G。数据库日志中搜索block,能搜到block的话就是存在数据库死锁,找到日志,查看对应的sql,优化造成死锁的sql。
现象:容量测试压测一段时间后,LR报连接超时错误。
原因:造成这种现象的原因很多,比如带宽不够,中间件线程池不够用,数据库连接池不够,连接数占满等都会造成连接不上而报超时错误。
解决:
去mysql数据库查看应用程序到数据库的连接有多少个
呈现代码宏出错: 参数’com.atlassian.confluence.ext.code.render.InvalidValueException’的值无效
通过命令:
show variables like ‘%max_connections%’; 查询设置的最大连接数;
show status like 'Threads%'查询当前的连接数是多少
show processlist/show full processlist;
如果当前连接数大于等于最大连接数,说明数据库连接池被占满,需要把最大连接数修改大一点
呈现代码宏出错: 参数’com.atlassian.confluence.ext.code.render.InvalidValueException’的值无效
一般在/etc/my.cnf里面修改 max_connections = xxxx
或通过命令:set global max_connections=xxxx 进行设置
复测看是否还会出现问题,如果出现去数据库查看连接,如果当前连接数大于等于最大连接数,则可以确定是数据库连接池不释放导致的。查看代码,数据库连接部分是不是有创建连接但是没有关闭连接的情况。基本就是这种情况导致的,修改代码即可。
现象:No operations allowed after connection closed,日志发现此报错,问题出在mysql。
原因:数据库的连接被创建后,如果没有手动关闭连接,mysql默认是8小时之后回收连接,如果超过8个小时,应用程序不去访问数据库,数据库就会断掉连接,当程序调用此连接时,到数据库才发现,此连接已经失效了,这时访问就会抛出此异常。
解决:涉及两个参数interactive_timeout和wait_timeout,默认是8小时,延长时间。修改mysql配置文件:vi /etc/my.cnf, 在[mysqld]区域添加这两项,然后重启数据库解决。
1)网络带宽
在压力测试中,有时候要模拟大量的用户请求,如果单位时间内传递的数据包过大,超过了带宽的传输能力,那么就会造成网络资源竞争,间接导致服务端接收到的请求数达不到服务端的处理能力上限。可以通过:直接复制文件传输到另一台服务器 初步查看网速是否达到网络带宽上限(scp -r -P 端口号 root@123.123.123.123:/root/
如网络带宽为100M时,可传输的最大网速为 12M/s 左右。
2)连接池
最大连接数太少,造成请求等待。连接池一般分为服务器中间件连接池(比如Tomcat)和数据库连接池(或者理解为最大允许连接数也行)。
3)垃圾回收机制
从常见的应用服务器来说,比如Tomcat,如果堆内存设置比较小,就会造成新生代的Eden区频繁的进行Young GC,老年代的Full GC也回收较频繁,那么对TPS也是有一定影响的,因为垃圾回收时通常会暂停所有线程的工作。
4)数据库
高并发情况下,如果请求数据需要写入数据库,且需要写入多个表的时候,如果数据库的最大连接数不够,或者写入数据的SQL没有索引没有绑定变量,抑或没有主从分离、读写分离等,就会导致数据库事务处理过慢,影响到TPS。
5)硬件资源
包括CPU(配置、使用率等)、内存(占用率等)、磁盘(I/O、页交换等)。
6)压力机
比如Jmeter和Loadrunner,单机负载能力有限,如果需要模拟的用户请求数超过其负载极限,也会间接影响TPS(这个时候就需要进行分布式压测来解决其单机负载的问题)。
7)业务逻辑
业务解耦度较低,较为复杂,整个事务处理线被拉长也会导致TPS上不去。
出现TPS波动较大问题的原因一般有网络波动、其他服务资源竞争以及垃圾回收问题这三种。
性能测试环境一般都是在内网或者压测机和服务在同一网段,可通过监控网络的出入流量来排查;(局域网可以不考虑)
其他服务资源竞争也可能造成这一问题,可以通过Top命令或服务梳理方式来排查在压测时是否有其他服务运行导致资源竞争;
垃圾回收问题相对来说是最常见的导致TPS波动的一种原因,可以通过GC监控命令来排查(jstat -gc PID 300 10)
原因:一般来说,出现这种问题的原因是因为线程block导致,当然不排除其他可能;
解决:如果是线程阻塞问题,修改线程策略,然后重新验证即可;
压测过程中,LR结果显示事务响应时间长
针对mysql:首先打开数据库的慢查询,通过命令找到执行比较久的SQL语句:mysql dump slow;分析是由于索引问题还是其他问题。
针对oracle:我们可以打AWR报告,通过报告分析,主要关注SQL ordered by Elapsed Time和SQL ordered by CPU Time两项,找出数据库sql问题。
现象:在压测过程中,服务器返回500错误
分析:500错误表示服务器内部错误,出现此错误时,我们首先查看服务器日志,通过错误日志信息定位具体错误的原因,如果出现get null from pool,说明数据库成为瓶颈,连接数不够导致,此时可以通过调整数据库连接池大小解决。
现象:在压测过程中,服务器返回502错误
分析:502一般是网关错误,同时nginx中会出现Connection reset by peer,出现此类报错的常见原因有:并发数大于服务端最大连接数,服务端会将其中一些连接关闭掉。
准备测试数据的方法 | 描述 |
---|---|
生成随机数据 | 使用随机数据生成器来生成测试数据,确保数据的多样性和充分性。 |
使用真实数据 | 使用真实的数据来模拟真实场景,并确保数据的安全性和隐私性。 |
数据库复制 | 从生产环境中复制一份真实数据到测试环境中,以模拟真实的测试环境。 |
数据库还原 | 从备份中还原一份数据到测试环境中,以模拟真实的测试环境。 |
数据库填充 | 使用脚本和工具来填充测试数据,确保数据的充分性和多样性。 |
在准备测试数据时,还需要注意以下几点:
数据准备时的方法 | 描述 |
---|---|
数据的准确性 | 确保测试数据的准确性和完整性,以避免测试结果的误差。 |
数据的安全性 | 确保测试数据的安全性和隐私性,避免泄露敏感信息。 |
数据的多样性 | 确保测试数据的多样性和充分性,以模拟真实的测试环境。 |
在进行压测之前,需要做以下准备:
压测前准备 | 描述 |
---|---|
确定测试目标 | 明确压测的目标,包括测试系统的性能、稳定性、吞吐量等方面的指标,以便于设计测试方案和评估测试结果。 |
确定测试场景 | 根据实际场景,设计测试场景,包括用户数量、请求类型、请求频率、请求参数等,以尽可能模拟真实的业务场景。 |
准备测试环境 | 搭建测试环境,包括部署应用程序、数据库、缓存、负载均衡等组件,以便于进行测试。 |
设置测试工具 | 选择合适的测试工具,如JMeter、LoadRunner等,并进行配置和调试,以便于进行测试。 |
编写测试脚本 | 根据测试目标和测试场景,编写测试脚本,包括模拟用户请求、处理请求结果、输出测试结果等,以便于进行自动化测试。 |
在进行压测时,可能会遇到以下问题:
压测可能遇到的问题备 | 描述 | 解决方法 |
---|---|---|
性能瓶颈 | 测试结果显示系统的性能不足或存在瓶颈,此时需要对系统进行优化和调整,以提高系统的性能和稳定性。 | 通过分析测试结果,确定系统存在的问题和瓶颈,并采取相应的优化和调整措施。 |
响应时间过长 | 测试结果显示系统的响应时间过长,此时需要对系统进行优化和调整,以缩短响应时间和提高用户体验。 | 对于资源耗尽的问题,可以增加系统的资源,如增加CPU、内存、磁盘等,以满足系统的需求。 |
资源耗尽 | 测试过程中可能会出现资源耗尽的情况,如CPU、内存、磁盘等资源的耗尽,此时需要对系统进行优化和调整,以避免资源浪费和系统崩溃。 | 对于系统响应时间过长的问题,可以对系统进行优化和调整,如调整系统参数、优化数据库查询语句等,以提高系统的响应速度。 |
网络问题 | 测试过程中可能会出现网络问题,如网络延迟、网络抖动等,此时需要对网络进行优化和调整,以提高网络的稳定性和可靠性。 | 对于网络问题,可以对网络进行优化和调整,如调整网络带宽、增加网络设备等,以提高网络的稳定性和可靠性。 |
**QPS 其实是衡量吞吐量(Throughput)的一个常用指标。**一个有着简单业务逻辑(包括数据库访问)的程序在单核心运行时可以提供 50 – 100 左右的 QPS,即每秒可以处理 50 – 100 个请求。
大部分请求的响应时间在 15 – 30 毫秒左右,如果每个请求花费 15 毫秒的话,那么每秒可以处理 66 个请求,也就是我们前面提到的 66 QPS;而如果都是复杂的请求,每个需要 30 毫秒的话,那么服务器就只有 33 QPS 了。
由上得出:
吞吐量(QPS/TPS)= 处理能力(CPU)/ 响应时间
吞吐量(QPS/TPS)= 并发数/ 响应时间
QPS = 并发数 / RT,由此可知,并发数越大, QPS越大。但是QPS还与响应时间成反比,响应时间越大,QPS就会越小。故:
最佳线程数目 = ((线程等待时间+线程CPU时间)/线程CPU时间 )* CPU数目
那么,如果服务器CPU核数为4核,一个任务线程cpu耗时为20ms,线程等待(网络IO、磁盘IO)耗时80ms,那最佳线程数目:( 80 + 20 )/20 * 4 = 20
事实上业务太多,怎么设置呢?这个就是要去压力测试去调整。不过我们的前辈已经帮我们总结了一个基础的值。
操作内存处理的业务,一般线程数设置为:
CPU核数 + 1 或者 CPU核数 * 2。核数为4的话,一般设置 5 或 8
文件操作,网络操作,数据库操作
cpu核数 / (1-0.9) 核数为4的话,一般设置 40
压测工具Jmeter、Locust,一定要编写好压力测试案例。