在操作系统中,是指一个时间段中有几个程序都处于已启动运行到运行完毕之间,且这几个程序都是在同一个处理机上运行。
就像前面提到的操作系统的时间片分时调度。打游戏和听音乐两件事情在同一个时间段内都是在同一台电脑上完成了从开始到结束的动作。那么,就可以说听音乐和打游戏是并发的。
我们两个人在吃午饭。你在吃饭的整个过程中,吃了米饭、吃了蔬菜、吃了牛肉。吃米饭、吃蔬菜、吃牛肉这三件事其实就是并发执行的。
对于你来说,整个过程中看似是同时完成的的。但其实你是在吃不同的东西之间来回切换的。
还是我们两个人吃午饭。在吃饭过程中,你吃了米饭、蔬菜、牛肉。我也吃了米饭、蔬菜和牛肉。
我们两个人之间的吃饭就是并行的。两个人之间可以在同一时间点一起吃牛肉,或者一个吃牛肉,一个吃蔬菜。之间是互不影响的。
所以,并发是指在一段时间内宏观上多个程序同时运行。并行指的是同一个时刻,多个任务确实真的在同时运行。
并发和并行的区别:
并发,指的是多个事情,在同一时间段内同时发生了。
并行,指的是多个事情,在同一时间点上同时发生了。
并发的多个任务之间是互相抢占资源的。
并行的多个任务之间是不互相抢占资源的、
只有在多CPU的情况中,才会发生并行。否则,看似同时发生的事情,其实都是并发执行的。
高并发和多线程”总是被一起提起,给人感觉两者好像相等,实则 高并发 ≠ 多线程(他们没有必然的直接联系)
高并发就是大家臆想的吹牛逼,其实大部分业务场景不存在并发竞争数据的情况,那么加服务 加机器基本上都能解决问题,你要事务压力大 那就分表,要是查询压力大 就主从 + 缓存,总有办法解决问题的。
在了解qps、tps、rt、并发数之前,首先我们应该明确一个系统的吞吐量到底代表什么含义,一般来说,系统吞吐量指的是系统的抗压、负载能力,代表一个系统每秒钟能承受的最大用户访问量。
一个系统的吞吐量通常由qps(tps)、并发数来决定,每个系统对这两个值都有一个相对极限值,只要某一项达到最大值,系统的吞吐量就上不去了。
所谓的系统吞吐量其实就是 : 系统每秒请求数
Queries Per Second,每秒查询数,即是每秒能够响应的查询次数,注意这里的查询是指用户发出请求到服务器做出响应成功的次数,简单理解可以认为查询=请求request。
qps=每秒钟request数量
Transactions Per Second 的缩写,每秒处理的事务数。一个事务是指一个客户机向服务器发送请求然后服务器做出反应的过程。客户机在发送请求时开始计时,收到服务器响应后结束计时,以此来计算使用的时间和完成的事务个数。
tps=每秒钟事务数量
如果单个接口请求,QPS = TPS ,但是观察这个变量的维度不一样,如果从请求的发起到请求的结束,且中间没有任何服务的远程调用,那么QPS = TPS 是没有任何疑义的,但是如果存在多个远程调用的话,就那么对于一台服务器 QPS = TPS 也是没有问题的,但是站在整个请求链路来说 ,QPS > TPS
Response Time缩写,简单理解为系统从输入到输出的时间间隔,宽泛的来说,他代表从客户端发起请求到服务端接受到请求并响应所有数据的时间差。一般取平均响应时间。
对于RT,客户端和服务端是大不相同的,因为请求从客户端到服务端,需要经过广域网,所以客户端RT往往远大于服务端RT,同时客户端的RT往往决定着用户的真实体验,服务端RT往往是评估我们系统好坏的一个关键因素。
并发数:
简而言之,系统能同时处理的请求/事务数量。
计算方式:
QPS=并发数/RT 或者 并发数=QPS*RT
举个栗子:
假设公司每天早上9点到10点1个小时内都有员工要上厕所,公司有3600个员工,平均每个员工上厕所时间为10分钟,我们来计算一下。
QPS = 3600/60*60 1
RT = 10*60 600秒
并发数 = 1 * 600 600
这样就意味着如果想达到最好的蹲坑体验,公司需要600个坑位来满足员工需求,否则的话上厕所就要排队等待了。
等到服务上线后,在业务压力的冲击下,会发现程序运行非常的慢,或者是宕机,莫名其妙的出现各种问题,只会进行一些无脑的扩容,扩容真的能解决问题吗??
可能能解决问题,但是同时也会带来一些其他的问题,因此在项目上线之前,还必须要有一步性能压力测试的步骤,以便于发现服务的一些问题,提前对服务的问题进行修复,优化等等。
项目打包: 可以使用idea直接打包上传,也可以在gitlab服务器直接通过maven进行打包,或者使用jenkins来进行打包,现在我们先使用idea的maven进行打包。
idea的maven打包:
注意: 打包服务的时候必须注意服务的配套的ip地址,由于此时服务和mysql,redis都在同一个服务器上,因此连接访问地址设置为localhost即可。
启动命令: java -jar jshop-web-1.0-SNAPSHOT.jar
注意:服务器部署的时候,由于服务器环境的不同,往往都需要额外的修改服务的配置文件,重新编译打包,必须服务器ip地址,本地开发环境的ip和线上的ip是不一样的,部署的时候,每次都需要修改这些配置,非常麻烦。因此服务部署时候应该具有一个外挂配置文件的能力。
外挂配置文件使用本地连接地址:
创建deploy.sh 这样一个shell脚本文件,执行java程序的后端启动工作
浏览器接口测试访问,发现服务已经启动成功:
压测目标:
线程梯度:500、1000,1500,2000,2500,3000个线程,即模拟这些数目的用户并发;
时间设置:Ramp-up period(inseconds)的值设为1(即1s,5s,10s启动500、1000,1500,2000,2500,3000并发访问)
循环次数:50次
1)设置压测请求
聚合报告:添加聚合报告
查看结果树:添加查看结果树
TPS统计分析:每秒事务数
服务器性能监控:CPU、内存、IO
注意: 对于jmeter的cpu监控来说,只能监控单核cpu,没有太大的参考价值,真实测试可以使用top指令观察cpu使用情况。
我们设置线程数 n = 5,循环次数a = 1000,请求www.google.com,得到聚合报告如图:
)
图中得到谷歌首页的平均请求时间大约为t = 0.2秒
这里,我们为了方便分析,将Ramp-Up Period 设置为T = 10秒(实际合理的时间后面会说明)
依然是n = 5,得到 S = (T- T/n) = 8 ,也就是说,从第一个线程启动到第8秒的时候,最后一个线程开始启动,若需要在最后一个线程启动的时候第一个线程仍未关闭,则需要满足 a·t > S ,已知S = 8,t = 0.2,得到 a > 40 。
OK,既然循环次数要大于40,我们不妨把循环设置成100,那么单个线程运行时间就是R = a·t = 20秒,也就是说第一个线程会在第20秒的时候停止,整个测试的理论运行时间为 S + R = (1-1/n)·T + a·t = 28秒
我们用一张图来直观的看看每个线程的运行情况
从图中可以得到从第8秒开始,到第20秒,5个线程同时在运行中,此时才是真正的模拟5个用户同时并发
说了这么多,我们的目的到底是什么?无非是如何设置线程数,Ramp-Up Period以及循环次数。线程数我就不多说了,看各个项目的测试需求,而刚刚我说了这么多,实质上只是介绍了一些概念和如何合理的设置循环次数,至于Ramp-Up Period如何合理这是,请看下面大神的分析。
聚合报告:TPS 3039 ,但是在这里看不见TPS的峰值是多少,需要进行改进
使用Tps监控曲线图:
可以看见,TPS在1s+的位置,TPS能力最大,其他时候TPS都一直平稳过渡。
随着并发压力的加大,以及时间延长,系统性能所发生的变化。正常情况下,平均采样响应时长曲线应该是平滑的,并大致平行于图形下边界。
随着并发压力的加大,以及时间延长,系统性能所发生的变化。正常情况下,平均采样响应时长曲线应该是平滑的,并大致平行于图形下边界。
可能存在性能问题:
①平均值在初始阶段跳升,而后逐渐平稳起来
一是系统在初始阶段存在性能缺陷,需要进一步优化,如数据库查询缓慢
二是系统有缓存机制,而性能测试数据在测试期间没有变化,如此一来同样的数据在初始阶段的响应时长肯定较慢;这属于性能测试数据准备的问题,不是性能缺陷,需调整后在测试
三是系统架构设计导致的固有现象,例如在系统接收到第一个请求后,才去建立应用服务器到数据库的链接,后续一段时间内不会释放连接。
②平均值持续增大,图片变得越来越陡峭
一是可能存在内存泄漏,此时可以通过监控系统日志、监控应用服务器状态等常见方法,来定位问题。
③平均值在性能测试期间,突然发生跳变,然后又恢复正常
一是可能存在系统性能缺陷
二是可能由于测试环境不稳定所造成的(检查应用服务器状态【CPU占用、内存占用】或者检查测试环境网络是否存在拥塞)
Springboot开发的服务使用内嵌的tomcat服务器来启动服务,那么tomcat配置使用的是默认配置,我们需要对tomcat配置进行一些适当的优化,让tomcat性能得以提升。
当然内嵌tomcat内嵌线程池的配置也是比较小的,我们可以通过外挂配置文件,把tomcat的相关配置进行改写,然后重新启动服务器进行测试。修改配置如下所示:
Tomcat的maxConnections、maxThreads、acceptCount三大配置,分别表示最大连接数,最大线程数、最大的等待数,可以通过application.yml配置文件来改变这个三个值,一个标准的示例如下:
1)、accept-count:最大等待数
官方文档的说明为:当所有的请求处理线程都在使用时,所能接收的连接请求的队列的最大长度。当队列已满时,任何的连接请求都将被拒绝。accept-count的默认值为100。 详细的来说:当调用HTTP请求数达到tomcat的最大线程数时,还有新的HTTP请求到来,这时tomcat会将该请求放在等待队列中,这个acceptCount就是指能够接受的最大等待数,默认100。如果等待队列也被放满了,这个时候再来新的请求就会被tomcat拒绝(connection refused)。
2)、maxThreads:最大线程数
每一次HTTP请求到达Web服务,tomcat都会创建一个线程来处理该请求,那么最大线程数决定了Web服务容器可以同时处理多少个请求。maxThreads默认200,肯定建议增加。但是,增加线程是有成本的,更多的线程,不仅仅会带来更多的线程上下文切换成本,而且意味着带来更多的内存消耗。JVM中默认情况下在创建新线程时会分配大小为1M的线程栈,所以,更多的线程异味着需要更多的内存。线程数的经验值为:1核2g内存为200,线程数经验值200;4核8g内存,线程数经验值800。
3)、maxConnections:最大连接数
官方文档的说明为:
这个参数是指在同一时间,tomcat能够接受的最大连接数。对于Java的阻塞式BIO,默认值是maxthreads的值;如果在BIO模式使用定制的Executor执行器,默认值将是执行器中maxthreads的值。对于Java 新的NIO模式,maxConnections 默认值是10000。 对于windows上APR/native IO模式,maxConnections默认值为8192,这是出于性能原因,如果配置的值不是1024的倍数,maxConnections 的实际值将减少到1024的最大倍数。 如果设置为-1,则禁用maxconnections功能,表示不限制tomcat容器的连接数。 maxConnections和accept-count的关系为:当连接数达到最大值maxConnections后,系统会继续接收连接,但不会超过acceptCount的值。
最近在用jmeter做压力测试时,发现一个问题,当线程持续上升到某个值时,报错:java.net.BindException: Address already in use: connect,如下图所示:
原因:windows提供给TCP/IP链接的端口为 1024-5000,并且要四分钟来循环回收它们,就导致我们在短时间内跑大量的请求时将端口占满了,导致如上报错。
解决办法(在jmeter所在服务器操作):
1.cmd中输入regedit命令打开注册表;
2.在 HKEY_LOCAL_MACHINESYSTEMCurrentControlSetServicesTcpipParameters右键Parameters;
3.添加一个新的DWORD,名字为MaxUserPort;
4.然后双击MaxUserPort,输入数值数据为65534,基数选择十进制;
5.完成以上操作,务必重启机器,问题解决,亲测有效;
未优化测试性能对比表:
优化后性能对比表:
性能测试对比:
长连接会消耗大量资源,如果连接不能及时释放,系统的TPS就提升不上去,因此我们需要改造web服务,提升web服务的长连接的性能。
TCP状态转移要点 TCP协议规定,对于已经建立的连接,网络双方要进行四次握手才能成功断开连接,如果缺少了其中某个步骤,将会使连接处于假死状态,连接本身占用的资源不会被释放。网络服务器程序要同时管理大量连接,所以很有必要保证无用连接完全断开,否则大量僵死的连接会浪费许多服务器资源。在众多TCP状态中,最值得注意的状态有两个:CLOSE_WAIT和TIME_WAIT。
1、LISTENING状态 FTP服务启动后首先处于侦听(LISTENING)状态。
2、ESTABLISHED状态 ESTABLISHED的意思是建立连接。表示两台机器正在通信。
*3、CLOSE_WAIT*
*对方主动关闭连接或者网络异常导致连接中断*,这时我方的状态会变成CLOSE_WAIT 此时我方要调用close()来使得连接正确关闭
*4、TIME_WAIT*
*我方主动调用close()断开连接,收到对方确认后状态变为TIME_WAIT*。TCP协议规定TIME_WAIT状态会一直持续2MSL(即两倍的分段最大生存期),以此来确保旧的连接状态不会对新连接产生影响。处于TIME_WAIT状态的连接占用的资源不会被内核释放,所以作为服务器,在可能的情况下,尽量不要主动断开连接,以减少TIME_WAIT状态造成的资源浪费。
目前有一种避免TIME_WAIT资源浪费的方法,就是关闭socket的LINGER选项。但这种做法是TCP协议不推荐使用的,在某些情况下这个操作可能会带来错误。
socket的状态
CLOSED没有使用这个套接字[netstat 无法显示closed状态]LISTEN套接字正在监听连接[调用listen后]SYN_SENT套接字正在试图主动建立连接[发送SYN后还没有收到ACK]SYN_RECEIVED正在处于连接的初始同步状态[收到对方的SYN,但还没收到自己发过去的SYN的ACK]ESTABLISHED连接已建立CLOSE_WAIT远程套接字已经关闭:正在等待关闭这个套接字[被动关闭的一方收到FIN]FIN_WAIT_1套接字已关闭,正在关闭连接[发送FIN,没有收到ACK也没有收到FIN]CLOSING套接字已关闭,远程套接字正在关闭,暂时挂起关闭确认[在FIN_WAIT_1状态下收到被动方的FIN]LAST_ACK远程套接字已关闭,正在等待本地套接字的关闭确认[被动方在CLOSE_WAIT状态下发送FIN]FIN_WAIT_2套接字已关闭,正在等待远程套接字关闭[在FIN_WAIT_1状态下收到发过去FIN对应的ACK]TIME_WAIT这个套接字已经关闭,正在等待远程套接字的关闭传送[FIN、ACK、FIN、ACK都完毕,这是主动方的最后一个状态,在过了2MSL时间后变为CLOSED状态]
状态变迁图:(tcp连接状态变迁图)
Java NIO的服务端只需启动一个专门的线程来处理所有的 IO 事件,这种通信模型是怎么实现的呢?呵呵,我们一起来探究它的奥秘吧。java NIO采用了双向通道(channel)进行数据传输,而不是单向的流(stream),在通道上可以注册我们感兴趣的事件。一共有以下四种事件:
服务端和客户端各自维护一个管理通道的对象,我们称之为selector,该对象能检测一个或多个通道 (channel) 上的事件。 我们以服务端为例,如果服务端的selector上注册了读事件,某时刻客户端给服务端发送了一些数据,阻塞I/O这时会调用read()方法阻塞地读取数据,而NIO的服务端会在selector中添加一个读事件。服务端的处理线程会轮询地访问selector,如果访问selector时发现有感兴趣的事件到达,则处理这些事件,如果没有感兴趣的事件到达,则处理线程会一直阻塞直到感兴趣的事件到达为止。 下面是我理解的java NIO的通信模型示意图:
Selector。可以说它是NIO中最关键的一个部分,Selector的作用就是用来轮询每个注册的Channel,一旦发现Channel有注册的事件发生,便获取事件然后进行处理。
从一个客户端向服务端发送数据,然后服务端接收数据的过程。客户端发送数据时,必须先将数据存入Buffer中,然后将Buffer中的内容写入通道。服务端这边接收数据必须通过Channel将数据读入到Buffer中,然后再从Buffer中取出数据来处理。
查询springboot内置tomcat使用的io类型,源码简单分析:
使用nio2的http协议对请求进行改写,看服务器性能是否有提升
Java 语言是当前互联网应用最为广泛的语言,作为一名 Java 程序猿,当业务相对比较稳定之后平常工作除了 coding 之外,大部分时间(70%~80%)是会用来排查突发或者周期性的线上问题。
由于业务应用 bug(本身或引入第三方库)、环境原因、硬件问题等原因,Java 线上服务出现故障 / 问题几乎不可避免。例如,常见的现象包括部分请求超时、用户明显感受到系统发生卡顿等等。
尽快线上问题从系统表象来看非常明显,但排查深究其发生的原因还是比较困难的,因此对开发测试或者是运维的同学产生了许多的困扰。
排查定位线上问题是具有一定技巧或者说是经验规律的,排查者如果对业务系统了解得越深入,那么相对来说定位也会容易一些。
不管怎么说,掌握 Java 服务线上问题排查思路并能够熟练排查问题常用工具 / 命令 / 平台是每一个 Java 程序猿进阶必须掌握的实战技能。
所有 Java 服务的线上问题从系统表象来看归结起来总共有四方面:CPU、内存、磁盘、网络。例如 CPU 使用率峰值突然飚高、内存溢出 (泄露)、磁盘满了、网络流量异常、FullGC 等等问题。
基于这些现象我们可以将线上问题分成两大类: 系统异常、业务服务异常。
常见的系统异常现象包括: CPU 占用率过高、CPU 上下文切换频率次数较高、磁盘满了、磁盘 I/O 过于频繁、网络流量异常 (连接数过多)、系统可用内存长期处于较低值 (导致 oom killer) 等等。
这些问题可以通过 top(cpu)、free(内存)、df(磁盘)、dstat(网络流量)、pstack、vmstat、strace(底层系统调用) 等工具获取系统异常现象数据。
此外,如果对系统以及应用进行排查后,均未发现异常现象的更笨原因,那么也有可能是外部基础设施如 IAAS 平台本身引发的问题。
常见的业务服务异常现象包括: PV 量过高、服务调用耗时异常、线程死锁、多线程并发问题、频繁进行 Full GC、异常安全攻击扫描等。
我们一般会采用排除法,从外部排查到内部排查的方式来定位线上服务问题。
- 首先我们要排除其他进程 (除主进程之外) 可能引起的故障问题;
- 然后排除业务应用可能引起的故障问题;
- 可以考虑是否为运营商或者云服务提供商所引起的故障。
问题定位流程,在linux系统中排查问题的方法,流程。
Linux 常用的性能分析工具使用包括 : top(cpu)、free(内存)、df(磁盘)、dstat(网络流量)、pstack、vmstat、strace(底层系统调用) 等。
CPU 是系统重要的监控指标,能够分析系统的整体运行状况。监控指标一般包括运行队列、CPU 使用率和上下文切换等。
top 命令是 Linux 下常用的 CPU 性能分析工具 , 能够实时显示系统中各个进程的资源占用状况 , 常用于服务端性能分析。
内存是排查线上问题的重要参考依据,内存问题很多时候是引起 CPU 使用率较高的见解因素。
系统内存:free 是显示的当前内存的使用 ,-m 的意思是 M 字节来显示内容。
dstat 命令集成了 vmstat、iostat、netstat lsof 等等工具能完成的任务。
1)vmstat指令详解:
2)lsof: 用于查看你进程开打的文件,打开文件的进程,进程打开的端口(TCP、UDP)。找回/恢复删除的文件
3)dstat -c cpu 情况 -d 磁盘读写 -n 网络状况 -l 显示系统负载 -m 显示形同内存状况 -p 显示系统进程信息 -r 显示系统 IO 情况
注: 如果没有dstat指令,需要下载(yum -y install dstat)
4)pstack strace
在 JDK 安装目录的 bin 目录下默认提供了很多有价值的命令行工具。每个小工具体积基本都比较小,因为这些工具只是 jdklib ools.jar 的简单封装。
其中,定位排查问题时最为常用命令包括:jps(进程)、jmap(内存)、jstack(线程)、jinfo(参数) 等。
- jps: 查询当前机器所有 JAVA 进程信息;
- jmap: 输出某个 java 进程内存情况 (如:产生那些对象及数量等);
- jstack: 打印某个 Java 线程的线程栈信息;
- jinfo: 用于查看 jvm 的配置参数。
jps 用于输出当前用户启动的所有进程 ID,当线上发现故障或者问题时,能够利用 jps 快速定位对应的 Java 进程 ID
当然,我们也可以使用 Linux 提供的查询进程状态命令,例如:
jmap 可以查看 JVM 进程的内存分配与使用情况,使用 的 GC 算法等信息。
printf ‘%x ’ tid –> 10 进制至 16 进制线程 ID(navtive 线程)
10 进制: jstack pid | grep tid -C 30 –color
ps方法查询当前线程tid,以及当前线程占用的时间长度: ps -mp 8278 -o THREAD,tid,time | head -n 40
某 Java 进程 CPU 占用率高,我们想要定位到其中 CPU 占用率最高的线程。
VisualVM,能够监控线程,内存情况,查看方法的CPU时间和内存中的对 象,已被GC的 对象,反向查看分配的堆栈(如100个String对象分别由哪几个对象分配出来的)。 VisualVM使用简单,几乎0配置,功能还是比较丰富的,几乎囊括了其它JDK自带命令的 所有功能。
1)监控远程jvm VisualJVM不仅是可以监控本地jvm进程,还可以监控远程的jvm进程,需要借助于JMX技术实现。
2)什么是JMX?
JMX(Java Management Extensions,即Java管理扩展)是一个为应用程序、设备、系统等植入管理功能的框架。JMX可以跨越一系列异构操作系统平台、系统体系结构和网络传输协议,灵活的开发无缝集成的系统、网络和服务管理应用。
3)监控远程的tomcat 想要监控远程的tomcat,就需要在远程的tomcat进行对JMX配置,方法如下:
保存退出,重启tomcat。
4)使用VisualJVM连接远程tomcat 添加远程主机: 在一个主机下可能会有很多的 jvm需要监控,所以接下来要在该主机上添加需要监控的 jvm:
连接成功。使用方法和前面就一样了,就可以和监控本地 jvm进程一样,监控远程的tomcat进程。
到此这篇服务端压力测试性能测试(服务器压力测试方法)的文章就介绍到这了,更多相关内容请继续浏览下面的相关推荐文章,希望大家都能在编程的领域有一番成就!版权声明:
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。
如若内容造成侵权、违法违规、事实不符,请将相关资料发送至xkadmin@xkablog.com进行投诉反馈,一经查实,立即处理!
转载请注明出处,原文链接:https://www.xkablog.com/te-xn/35448.html