研究表明,人的反应时间通常在0.2s左右,运动员0.14s已经是顶级反应了,所以响应时间在0.2秒以内通常是无感的。那么在性能测试时,需要关注哪些指标呢?

CPU:有的应用需要大量计算,他们会长时间、不间断地占用 CPU 资源,导致其他资源无法争夺到 CPU 而响应缓慢,从而带来系统性能问题。例如,代码递归导致的无限循环,正则表达式引起的回溯,JVM 频繁的 FULL GC,以及多线程编程造成的大量上下文切换等,这些都有可能导致 CPU 资源繁忙。

内存:Java 程序一般通过 JVM 对内存进行分配管理,主要是用 JVM 中的堆内存来存储 Java 创建的对象。系统堆内存的读写速度非常快,所以基本不存在读写性能瓶颈。但是由于内存成本要比磁盘高,相比磁盘,内存的存储空间又非常有限。所以当内存空间被占满,对象无法回收时,就会导致内存溢出、内存泄露等问题。

磁盘 I/O:磁盘相比内存来说,存储空间要大很多,但磁盘 I/O 读写的速度要比内存慢,虽然目前引入的 SSD 固态硬盘已经有所优化,但仍然无法与内存的读写速度相提并论。

网络:网络对于系统性能来说,也起着至关重要的作用。如果你购买过云服务,一定经历过,选择网络带宽大小这一环节。带宽过低的话,对于传输数据比较大,或者是并发量比较大的系统,网络就很容易成为性能瓶颈。

异常:Java 应用中,抛出异常需要构建异常栈,对异常进行捕获和处理,这个过程非常消耗系统性能。如果在高并发的情况下引发异常,持续地进行异常处理,那么系统的性能就会明显地受到影响。数据库:大部分系统都会用到数据库,而数据库的操作往往是涉及到磁盘 I/O 的读写。大量的数据库读写操作,会导致磁盘 I/O 性能瓶颈,进而导致数据库操作的延迟性。对于有大量数据库读写操作的系统来说,数据库的性能优化是整个系统的核心。

锁竞争:在并发编程中,我们经常会需要多个线程,共享读写操作同一个资源,这个时候为了保持数据的原子性(即保证这个共享资源在一个线程写的时候,不被另一个线程修改),我们就会用到锁。锁的使用可能会带来上下文切换,从而给系统带来性能开销。JDK1.6 之后,Java 为了降低锁竞争带来的上下文切换,对 JVM 内部锁已经做了多次优化,例如,新增了偏向锁、自旋锁、轻量级锁、锁粗化、锁消除等。而如何合理地使用锁资源,优化锁资源,就需要你了解更多的操作系统知识、Java 多线程编程基础,积累项目经验,并结合实际场景去处理相关问题。了解了上面这些基本内容,我们可以得到下面几个指标,来衡量一般系统的性能。响应时间响应时间是衡量系统性能的重要指标之一,响应时间越短,性能越好,一般一个接口的响应时间是在毫秒级

操作数据库的时间是请求接口中最耗时的操作,是操作内存的数个数量级耗时。

计算机资源分配使用率

通常由 CPU 占用率、内存使用率、磁盘 I/O、网络 I/O 来表示资源使用率。这几个参数好比一个木桶,如果其中任何一块木板出现短板,任何一项分配不合理,对整个系统性能的影响都是毁灭性的。

负载承受能力

当系统压力上升时,你可以观察,系统响应时间的上升曲线是否平缓。这项指标能直观地反馈给你,系统所能承受的负载压力极限。例如,当你对系统进行压测时,系统的响应时间会随着系统并发数的增加而延长,直到系统无法处理这么多请求,抛出大量错误时,就到了极限。

数据库响应时间:数据库操作所消耗的时间,往往是整个请求链中最耗时的;

服务端响应时间:服务端包括 Nginx 分发的请求所消耗的时间以及服务端程序执行所消耗的时间;

网络响应时间:这是网络传输时,网络硬件需要对传输的请求进行解析等操作所消耗的时间;

客户端响应时间:对于普通的 Web、App 客户端来说,消耗时间是可以忽略不计的,但如果你的客户端嵌入了大量的逻辑处理,消耗的时间就有可能变长,从而成为系统的瓶颈。

吞吐量

在测试中,我们往往会比较注重系统接口的 TPS(每秒事务处理量),因为 TPS 体现了接口的性能,TPS 越大,性能越好。在系统中,我们也可以把吞吐量自下而上地分为两种:磁盘吞吐量和网络吞吐量。

性能测试有哪些干扰因子?

了解了上述的关键指标后,性能测试就有了相应关注点。

精准定位哪个模块或者接口的性能问题,可以微基准性能测试,即不同实现方式下的性能对比。

考虑测试环境、测试场景和测试目标,可以通过宏基准性能测试。

模拟线上环境,然后看测试场景。我们需要确定在测试某个接口时,是否有其他业务接口同时也在平行运行,造成干扰。如果有,请重视,因为你一旦忽视了这种干扰,测试结果就会出现偏差。最后看测试目标。我们的性能测试是要有目标的,这里可以通过吞吐量以及响应时间来衡量系统是否达标。不达标,就进行优化;达标,就继续加大测试的并发数,探底接口的 TPS(最大每秒事务处理量),这样做,可以深入了解到接口的性能。观察服务器的 CPU、内存以及 I/O 使用率的变化。

性能测试时,系统会运行得越来越快,后面的访问速度要比我们第一次访问的速度快上几倍。热点代码,JVM会通过即时编译器(JIT compiler,just-in-time compiler)把这些代码编译成与本地平台相关的机器码,并进行各层次的优化,然后存储在内存中,之后每次运行代码时,直接从内存中获取。

多 JVM 情况下的影响:服务器有多个Java项目,部署在不同的 Tomcat 中,这就意味着服务器会有多个 JVM。任意一个  JVM 都拥有整个系统的资源使用权。原则上一台机器上只部署单独的一个 JVM,在做性能测试时,测试结果干扰少。所以我们应该避免环境中一台机器部署多个  JVM  的情况。

限流,对系统的入口设置最大访问限制。参考性能测试中探底接口的 TPS 。同时采取熔断措施,友好地返回没有成功的请求。

计算密集型,线程池参数调优,https://github.com/nickliuchao/threadpollsizetest,核心线程数一般设定为N+1,比 CPU 核心数多出来的一个线程是为了防止线程偶发的缺页中断,或者其它原因导致的任务暂停而带来的影响。IO密集型2N,实际情况根据线上压力进行增加或者减少核心线程数。

千万别漏了GC日志

-XX:+PrintGCDateStamps -XX:+PrintGCDetails -Xloggc:./gclogs

解释:

-XX:+PrintGCDateStamps 日期格式打印GC时间

-XX:+PrintGCDetails GC详细信息

-Xloggc:./gc.log GC日志 会根据系统自动修改/

jmeter测试注意事项:

线程名:IoT性能吞吐控制(带集合点。8:2读写并发) 测试任务集合1

线程名:IoT性能(带集合点。不同时进行读写)测试任务集合2

线程名:IoT性能无集合点(不带集合点)测试任务集合3

step1: 启用要测试的线程,禁用不测试的线程 只能跑一个任务,否则任务之间会彼此影响

step2:修改并发数 1)线程组下的“线程数” 2)用户自定义的变量中,sample 变量名,8:2的还要修改sample20%、sample80% 两个变量 3)用户登录数据文件位置要修改

step3:聚合报告修改运行结果保存路径 文件名后缀.jtl 【E:\项目\IoT\iot文档\username.jtl】 注意: 1、每跑一次,就改下文件名后缀,否则运行结果可能会覆盖或叠加 2、每次跑前点下清除或清楚全部按钮,把记录清除

IO测试

public class IOTypeTest implements Runnable {//整体执行时间,包括在队列中等待的时间Vector<Long> wholeTimeList;//真正执行时间Vector<Long> runTimeList;private long initStartTime = 0;/*** 构造函数* @param runTimeList* @param wholeTimeList*/public IOTypeTest(Vector<Long> runTimeList, Vector<Long> wholeTimeList) {initStartTime = System.currentTimeMillis();this.runTimeList = runTimeList;this.wholeTimeList = wholeTimeList;}/***IO操作* @param number* @return* @throws IOException */public void readAndWrite() throws IOException {File sourceFile = new File("D:/tets.txt");//创建输入流BufferedReader input = new BufferedReader(new FileReader(sourceFile));//读取源文件,写入到新的文件String line = null;while((line = input.readLine()) != null){System.out.println(line);}//关闭输入输出流input.close();}public void run() {long start = System.currentTimeMillis();try {try {Thread.sleep(2000);} catch (InterruptedException e) {// TODO Auto-generated catch blocke.printStackTrace();}readAndWrite();} catch (IOException e) {// TODO Auto-generated catch blocke.printStackTrace();}long end = System.currentTimeMillis();long wholeTime = end - initStartTime;long runTime = end - start;wholeTimeList.add(wholeTime);runTimeList.add(runTime);System.out.println("单个线程花费时间:" + (end - start));}}

CPU测试

import java.util.List;public class CPUTypeTest implements Runnable {//整体执行时间,包括在队列中等待的时间List<Long> wholeTimeList;//真正执行时间List<Long> runTimeList;private long initStartTime = 0;/*** 构造函数* @param runTimeList* @param wholeTimeList*/public CPUTypeTest(List<Long> runTimeList, List<Long> wholeTimeList) {initStartTime = System.currentTimeMillis();this.runTimeList = runTimeList;this.wholeTimeList = wholeTimeList;}/*** 判断素数* @param number* @return*/public boolean isPrime(final int number) {if (number <= 1)return false;for (int i = 2; i <= Math.sqrt(number); i++) {if (number % i == 0)return false;}return true;}/*** 計算素数* @param number* @return*/public int countPrimes(final int lower, final int upper) {int total = 0;for (int i = lower; i <= upper; i++) {if (isPrime(i))total++;}return total;}public void run() {long start = System.currentTimeMillis();try {Thread.sleep(1000);} catch (InterruptedException e) {// TODO Auto-generated catch blocke.printStackTrace();}countPrimes(1, 1000000);long end = System.currentTimeMillis();long wholeTime = end - initStartTime;long runTime = end - start;wholeTimeList.add(wholeTime);runTimeList.add(runTime);System.out.println("单个线程花费时间:" + (end - start));}}
import java.util.ArrayList;
import java.util.List;
import java.util.Vector;
import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.Future;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;/*** Hello world!**/
public class App {// 初始化线程池private static ThreadPoolExecutor threadPool = new ThreadPoolExecutor(8, 8, 10, TimeUnit.SECONDS, new ArrayBlockingQueue<Runnable>(1000), new ThreadPoolExecutor.DiscardOldestPolicy());public static void main(String[] args) throws InterruptedException, ExecutionException, TimeoutException {int cores = Runtime.getRuntime().availableProcessors();int requestNum = 100;System.out.println("CPU核数 " + cores);List<Future<?>> futureList = new ArrayList<Future<?>>();Vector<Long> wholeTimeList = new Vector<Long>();Vector<Long> runTimeList = new Vector<Long>();for (int i = 0; i < requestNum; i++) {Future<?> future = threadPool.submit(new CPUTypeTest(runTimeList, wholeTimeList));//Future<?> future = threadPool.submit(new IOTypeTest(runTimeList, wholeTimeList));futureList.add(future);}for (Future<?> future : futureList) {//获取线程执行结果future.get(requestNum, TimeUnit.SECONDS);}long wholeTime = 0;for (int i = 0; i < wholeTimeList.size(); i++) {wholeTime = wholeTimeList.get(i) + wholeTime;}long runTime = 0;for (int i = 0; i < runTimeList.size(); i++) {runTime = runTimeList.get(i) + runTime;}System.out.println("平均每个线程整体花费时间: " +wholeTime/wholeTimeList.size());System.out.println("平均每个线程执行花费时间: " +runTime/runTimeList.size());}
}
import junit.framework.Test;
import junit.framework.TestCase;
import junit.framework.TestSuite;/*** Unit test for simple App.*/
public class AppTest extends TestCase {/*** Create the test case** @param testName name of the test case*/public AppTest( String testName ) {super( testName );}/*** @return the suite of tests being tested*/public static Test suite() {return new TestSuite( AppTest.class );}/*** Rigourous Test :-)*/public void testApp() {assertTrue( true );}
}

Java工程进行性能测试时通常要考虑哪些要素,如何使接口响应时间在毫秒级范围,Java项目如何进行性能测试?0.2s的反应时间内返回响应,用户感知情况较好。附IO密集型和计算密集型性能测试摸底代码相关推荐

  1. IO密集型和CPU密集型程序-概念与实现

    欢迎关注笔者的微信公众号 概念 在计算机科学中,有两种不同类型的程序:IO 密集型和 CPU 密集型.这两种程序的主要差别在于它们在执行任务时瓶颈所在的地方. IO 密集型:这类程序主要通过读写磁盘文 ...

  2. io密集服务器cpu性能,IO密集型和CPU密集型 线程数的计算

    CPU密集型 每一个CPU核心都参与计算,将CPU的性能充分利用起来,这样才算是没有浪费服务器配置,如果在非常好的服务器配置上还运行着单线程程序那将是多么重大的浪费.对于计算密集型的应用,完全是靠CP ...

  3. io密集型和cpu密集型_和小胖一起理解CPU负载和利用率

    作者:小胖前言 凌晨一点,正整着炸鸡的小胖,微信一呼"你的服务器CPU持续超载 - " 麻溜的连上服务器,先把CPU负载摁下来.仔细一想,最近1分钟平均负载很大,但CPU利用率却≤ ...

  4. io密集型和cpu密集型_一次说明白Python爬虫中多线程,多进程,异步IO编程

    图/文:迷神 我们在Python爬虫中,重要的是讲究速度,如果有10万或者100万Url地址,写过爬虫的都会知道,那估计是非常慢的.我们的Python爬虫一般IO密集型业务,Python爬虫程序需要发 ...

  5. io密集型和cpu密集型java,如何设计CPU密集型与I/O密集型程序

    CPU密集型(CPU-Bound)是指系统指花费相对大部分时间在做CPU运算.逻辑判断等,CPU使用率很高,典型的如加密运算:I/O密集型(I/O-Bound)是指系统花费大部分时间在等待相对较慢的I ...

  6. IO密集型和CPU密集型

    系统有四大资源:CPU.内存.磁盘.网络 CPU密集型: 介绍:说明系统的瓶颈在CPU上面(比如做大量的运算.矩阵运算.计算圆周率.渲染等),此时性能瓶颈就在CPU上面,无论你磁盘读写多块,性能也上不 ...

  7. 导入Java工程到Eclipse时出现“selection does not contain”解决办法

    出现这个错误,请检查 新建java project时勾选"Use project folder for sources and class files". 导入的完整的文件夹,比如 ...

  8. 谈计算(cpu)密集型和io密集型与php性能优化

    这篇文章计划很久了一直感觉无从下手, 一直想全面.深入的写一篇关于php优化,但思绪很乱,经过很多天的构思和整理,终于有点头绪了. 几十年来,php以超高的开发效率.低成本的投入.内置丰富的函数库.灵 ...

  9. mysql密集计算_计算密集型和IO密集型

    什么是计算密集?举个例子,把SQLite数据库放到Linux内存文件系统/dev/shm上对100万数据进行SELECT查询操作,那么这个SELECT查询,在使用了B+树索引时,在B+树索引上的二分查 ...

最新文章

  1. 史上最全ajax全套讲解
  2. 寻找两个字符串相似度的代码
  3. new是不是c语言运算符优先级表,C语言运算符优先级列表(超详细)
  4. MyEclipse 10(汉化版)安装教程
  5. Cheatsheet: 2013 09.10 ~ 09.21
  6. UIActionSheet
  7. 对CORS OPTIONS预检请求的一些思考
  8. linux如何运行多个硬盘,一个硬盘如何装两个Linux
  9. 西昌学院计算机,西昌学院
  10. 原来 Sql Server 的存储过程是可以调试的
  11. OpenCV防止数据溢出saturate_cast
  12. openstack创建外网_OpenStack的女性谈论外展,教育和指导
  13. MTK 驱动(4)---MTK Android Driver知识大全
  14. log4j.properties中log4j.rootLogger 与log4j.rootCategory 有什么区别 .
  15. JSP实用教程(2)——JSP语法
  16. Video标签的常用属性操作
  17. 【sql】SQL3 查找当前薪水详情以及部门编号dept_no
  18. Excel引用外部数据链接地址修改/引用地址修改/公式更改
  19. Ubuntu搭建团队文档协作在线平台
  20. HTTP请求方式——GET请求

热门文章

  1. 三星android+5.0,三星TouchWiz终于好看了:多谢安卓5.0
  2. android必备软件清单[]
  3. JavaWeb 项目 --- 博客系统(前后分离)
  4. IDA memory dump
  5. vue源码解析compile
  6. Spring系列学习之Spring LDAP
  7. pandas中excel表的处理
  8. 从摆摊到知名水饺品牌,这位山东女子始终在用心做生意
  9. Oracle表明明存在SQL查询数据提示表不存在异常
  10. SP 导出 PS 有缝隙的问题