learn.lianglianglee.com/专栏/Java并发编程实战/加餐 推荐几款常用的性能测试工具.md.html
2022-05-11 18:57:05 +08:00

1047 lines
26 KiB
HTML
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<!DOCTYPE html>
<!-- saved from url=(0046)https://kaiiiz.github.io/hexo-theme-book-demo/ -->
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1.0, user-scalable=no">
<link rel="icon" href="/static/favicon.png">
<title>加餐 推荐几款常用的性能测试工具.md.html</title>
<!-- Spectre.css framework -->
<link rel="stylesheet" href="/static/index.css">
<!-- theme css & js -->
<meta name="generator" content="Hexo 4.2.0">
</head>
<body>
<div class="book-container">
<div class="book-sidebar">
<div class="book-brand">
<a href="/">
<img src="/static/favicon.png">
<span>技术文章摘抄</span>
</a>
</div>
<div class="book-menu uncollapsible">
<ul class="uncollapsible">
<li><a href="/" class="current-tab">首页</a></li>
</ul>
<ul class="uncollapsible">
<li><a href="../">上一级</a></li>
</ul>
<ul class="uncollapsible">
<li>
<a href="/专栏/Java并发编程实战/00 开篇词你为什么需要学习并发编程?.md.html">00 开篇词你为什么需要学习并发编程?.md.html</a>
</li>
<li>
<a href="/专栏/Java并发编程实战/01 如何制定性能调优标准?.md.html">01 如何制定性能调优标准?.md.html</a>
</li>
<li>
<a href="/专栏/Java并发编程实战/02 如何制定性能调优策略?.md.html">02 如何制定性能调优策略?.md.html</a>
</li>
<li>
<a href="/专栏/Java并发编程实战/03 字符串性能优化不容小觑百M内存轻松存储几十G数据.md.html">03 字符串性能优化不容小觑百M内存轻松存储几十G数据.md.html</a>
</li>
<li>
<a href="/专栏/Java并发编程实战/04 慎重使用正则表达式.md.html">04 慎重使用正则表达式.md.html</a>
</li>
<li>
<a href="/专栏/Java并发编程实战/05 ArrayList还是LinkedList使用不当性能差千倍.md.html">05 ArrayList还是LinkedList使用不当性能差千倍.md.html</a>
</li>
<li>
<a href="/专栏/Java并发编程实战/06 Stream如何提高遍历集合效率.md.html">06 Stream如何提高遍历集合效率.md.html</a>
</li>
<li>
<a href="/专栏/Java并发编程实战/07 深入浅出HashMap的设计与优化.md.html">07 深入浅出HashMap的设计与优化.md.html</a>
</li>
<li>
<a href="/专栏/Java并发编程实战/08 网络通信优化之IO模型如何解决高并发下IO瓶颈.md.html">08 网络通信优化之IO模型如何解决高并发下IO瓶颈.md.html</a>
</li>
<li>
<a href="/专栏/Java并发编程实战/09 网络通信优化之序列化避免使用Java序列化.md.html">09 网络通信优化之序列化避免使用Java序列化.md.html</a>
</li>
<li>
<a href="/专栏/Java并发编程实战/10 网络通信优化之通信协议如何优化RPC网络通信.md.html">10 网络通信优化之通信协议如何优化RPC网络通信.md.html</a>
</li>
<li>
<a href="/专栏/Java并发编程实战/11 答疑课堂深入了解NIO的优化实现原理.md.html">11 答疑课堂深入了解NIO的优化实现原理.md.html</a>
</li>
<li>
<a href="/专栏/Java并发编程实战/12 多线程之锁优化深入了解Synchronized同步锁的优化方法.md.html">12 多线程之锁优化深入了解Synchronized同步锁的优化方法.md.html</a>
</li>
<li>
<a href="/专栏/Java并发编程实战/13 多线程之锁优化深入了解Lock同步锁的优化方法.md.html">13 多线程之锁优化深入了解Lock同步锁的优化方法.md.html</a>
</li>
<li>
<a href="/专栏/Java并发编程实战/14 多线程之锁优化(下):使用乐观锁优化并行操作.md.html">14 多线程之锁优化(下):使用乐观锁优化并行操作.md.html</a>
</li>
<li>
<a href="/专栏/Java并发编程实战/15 多线程调优(上):哪些操作导致了上下文切换?.md.html">15 多线程调优(上):哪些操作导致了上下文切换?.md.html</a>
</li>
<li>
<a href="/专栏/Java并发编程实战/16 多线程调优(下):如何优化多线程上下文切换?.md.html">16 多线程调优(下):如何优化多线程上下文切换?.md.html</a>
</li>
<li>
<a href="/专栏/Java并发编程实战/17 并发容器的使用:识别不同场景下最优容器.md.html">17 并发容器的使用:识别不同场景下最优容器.md.html</a>
</li>
<li>
<a href="/专栏/Java并发编程实战/18 如何设置线程池大小?.md.html">18 如何设置线程池大小?.md.html</a>
</li>
<li>
<a href="/专栏/Java并发编程实战/19 如何用协程来优化多线程业务?.md.html">19 如何用协程来优化多线程业务?.md.html</a>
</li>
<li>
<a href="/专栏/Java并发编程实战/20 磨刀不误砍柴工欲知JVM调优先了解JVM内存模型.md.html">20 磨刀不误砍柴工欲知JVM调优先了解JVM内存模型.md.html</a>
</li>
<li>
<a href="/专栏/Java并发编程实战/21 深入JVM即时编译器JIT优化Java编译.md.html">21 深入JVM即时编译器JIT优化Java编译.md.html</a>
</li>
<li>
<a href="/专栏/Java并发编程实战/22 如何优化垃圾回收机制?.md.html">22 如何优化垃圾回收机制?.md.html</a>
</li>
<li>
<a href="/专栏/Java并发编程实战/23 如何优化JVM内存分配.md.html">23 如何优化JVM内存分配.md.html</a>
</li>
<li>
<a href="/专栏/Java并发编程实战/24 内存持续上升,我该如何排查问题?.md.html">24 内存持续上升,我该如何排查问题?.md.html</a>
</li>
<li>
<a href="/专栏/Java并发编程实战/25 答疑课堂:模块四热点问题解答.md.html">25 答疑课堂:模块四热点问题解答.md.html</a>
</li>
<li>
<a href="/专栏/Java并发编程实战/26 单例模式:如何创建单一对象优化系统性能?.md.html">26 单例模式:如何创建单一对象优化系统性能?.md.html</a>
</li>
<li>
<a href="/专栏/Java并发编程实战/27 原型模式与享元模式:提升系统性能的利器.md.html">27 原型模式与享元模式:提升系统性能的利器.md.html</a>
</li>
<li>
<a href="/专栏/Java并发编程实战/28 如何使用设计模式优化并发编程?.md.html">28 如何使用设计模式优化并发编程?.md.html</a>
</li>
<li>
<a href="/专栏/Java并发编程实战/29 生产者消费者模式:电商库存设计优化.md.html">29 生产者消费者模式:电商库存设计优化.md.html</a>
</li>
<li>
<a href="/专栏/Java并发编程实战/30 装饰器模式:如何优化电商系统中复杂的商品价格策略?.md.html">30 装饰器模式:如何优化电商系统中复杂的商品价格策略?.md.html</a>
</li>
<li>
<a href="/专栏/Java并发编程实战/31 答疑课堂:模块五思考题集锦.md.html">31 答疑课堂:模块五思考题集锦.md.html</a>
</li>
<li>
<a href="/专栏/Java并发编程实战/32 MySQL调优之SQL语句如何写出高性能SQL语句.md.html">32 MySQL调优之SQL语句如何写出高性能SQL语句.md.html</a>
</li>
<li>
<a href="/专栏/Java并发编程实战/33 MySQL调优之事务高并发场景下的数据库事务调优.md.html">33 MySQL调优之事务高并发场景下的数据库事务调优.md.html</a>
</li>
<li>
<a href="/专栏/Java并发编程实战/34 MySQL调优之索引索引的失效与优化.md.html">34 MySQL调优之索引索引的失效与优化.md.html</a>
</li>
<li>
<a href="/专栏/Java并发编程实战/35 记一次线上SQL死锁事故如何避免死锁.md.html">35 记一次线上SQL死锁事故如何避免死锁.md.html</a>
</li>
<li>
<a href="/专栏/Java并发编程实战/36 什么时候需要分表分库?.md.html">36 什么时候需要分表分库?.md.html</a>
</li>
<li>
<a href="/专栏/Java并发编程实战/37 电商系统表设计优化案例分析.md.html">37 电商系统表设计优化案例分析.md.html</a>
</li>
<li>
<a href="/专栏/Java并发编程实战/38 数据库参数设置优化,失之毫厘差之千里.md.html">38 数据库参数设置优化,失之毫厘差之千里.md.html</a>
</li>
<li>
<a href="/专栏/Java并发编程实战/39 答疑课堂MySQL中InnoDB的知识点串讲.md.html">39 答疑课堂MySQL中InnoDB的知识点串讲.md.html</a>
</li>
<li>
<a href="/专栏/Java并发编程实战/41 如何设计更优的分布式锁?.md.html">41 如何设计更优的分布式锁?.md.html</a>
</li>
<li>
<a href="/专栏/Java并发编程实战/42 电商系统的分布式事务调优.md.html">42 电商系统的分布式事务调优.md.html</a>
</li>
<li>
<a href="/专栏/Java并发编程实战/43 如何使用缓存优化系统性能?.md.html">43 如何使用缓存优化系统性能?.md.html</a>
</li>
<li>
<a href="/专栏/Java并发编程实战/44 记一次双十一抢购性能瓶颈调优.md.html">44 记一次双十一抢购性能瓶颈调优.md.html</a>
</li>
<li>
<a href="/专栏/Java并发编程实战/加餐 什么是数据的强、弱一致性?.md.html">加餐 什么是数据的强、弱一致性?.md.html</a>
</li>
<li>
<a class="current-tab" href="/专栏/Java并发编程实战/加餐 推荐几款常用的性能测试工具.md.html">加餐 推荐几款常用的性能测试工具.md.html</a>
</li>
<li>
<a href="/专栏/Java并发编程实战/答疑课堂:模块三热点问题解答.md.html">答疑课堂:模块三热点问题解答.md.html</a>
</li>
<li>
<a href="/专栏/Java并发编程实战/结束语 栉风沐雨,砥砺前行!.md.html">结束语 栉风沐雨,砥砺前行!.md.html</a>
</li>
</ul>
</div>
</div>
<div class="sidebar-toggle" onclick="sidebar_toggle()" onmouseover="add_inner()" onmouseleave="remove_inner()">
<div class="sidebar-toggle-inner"></div>
</div>
<script>
function add_inner() {
let inner = document.querySelector('.sidebar-toggle-inner')
inner.classList.add('show')
}
function remove_inner() {
let inner = document.querySelector('.sidebar-toggle-inner')
inner.classList.remove('show')
}
function sidebar_toggle() {
let sidebar_toggle = document.querySelector('.sidebar-toggle')
let sidebar = document.querySelector('.book-sidebar')
let content = document.querySelector('.off-canvas-content')
if (sidebar_toggle.classList.contains('extend')) { // show
sidebar_toggle.classList.remove('extend')
sidebar.classList.remove('hide')
content.classList.remove('extend')
} else { // hide
sidebar_toggle.classList.add('extend')
sidebar.classList.add('hide')
content.classList.add('extend')
}
}
function open_sidebar() {
let sidebar = document.querySelector('.book-sidebar')
let overlay = document.querySelector('.off-canvas-overlay')
sidebar.classList.add('show')
overlay.classList.add('show')
}
function hide_canvas() {
let sidebar = document.querySelector('.book-sidebar')
let overlay = document.querySelector('.off-canvas-overlay')
sidebar.classList.remove('show')
overlay.classList.remove('show')
}
</script>
<div class="off-canvas-content">
<div class="columns">
<div class="column col-12 col-lg-12">
<div class="book-navbar">
<!-- For Responsive Layout -->
<header class="navbar">
<section class="navbar-section">
<a onclick="open_sidebar()">
<i class="icon icon-menu"></i>
</a>
</section>
</header>
</div>
<div class="book-content" style="max-width: 960px; margin: 0 auto;
overflow-x: auto;
overflow-y: hidden;">
<div class="book-post">
<p id="tip" align="center"></p>
<div><h1>加餐 推荐几款常用的性能测试工具</h1>
<p>你好,我是刘超。很多同学给我留言想让我讲讲工具,所以我的第一篇加餐就光速来了~</p>
<p>熟练掌握一款性能测试工具,是我们必备的一项技能。他不仅可以帮助我们模拟测试场景(包括并发、复杂的组合场景),还能将测试结果转化成数据或图形,帮助我们更直观地了解系统性能。</p>
<h2>常用的性能测试工具</h2>
<p>常用的性能测试工具有很多,在这里我将列举几个比较实用的。</p>
<p>对于开发人员来说,首选是一些开源免费的性能(压力)测试软件,例如 abApacheBench、JMeter 等;对于专业的测试团队来说,付费版的 LoadRunner 是首选。当然,也有很多公司是自行开发了一套量身定做的性能测试软件,优点是定制化强,缺点则是通用性差。</p>
<p>接下来,我会为你重点介绍 ab 和 JMeter 两款测试工具的特点以及常规的使用方法。</p>
<h3>1.ab</h3>
<p>ab 测试工具是 Apache 提供的一款测试工具,具有简单易上手的特点,在测试 Web 服务时非常实用。</p>
<p>ab 可以在 Windows 系统中使用,也可以在 Linux 系统中使用。这里我说下在 Linux 系统中的安装方法,非常简单,只需要在 Linux 系统中输入 yum-y install httpd-tools 命令,就可以了。</p>
<p>安装成功后,输入 ab 命令,可以看到以下提示:</p>
<p><img src="assets/ac58706f86ebd1d7349561ae501fca0a.png" alt="img" /></p>
<p>ab 工具用来测试 post get 接口请求非常便捷,可以通过参数指定请求数、并发数、请求参数等。例如,一个测试并发用户数为 10、请求数量为 100 的的 post 请求输入如下:</p>
<pre><code>ab -n 100 -c 10 -p 'post.txt' -T 'application/x-www-form-urlencoded' 'http://test.api.com/test/register'
</code></pre>
<p>post.txt 为存放 post 参数的文档,存储格式如下:</p>
<pre><code>usernanme=test&amp;password=test&amp;sex=1
</code></pre>
<p><strong>附上几个常用参数的含义:</strong></p>
<ul>
<li>-n总请求次数最小默认为 1</li>
<li>-c并发次数最小默认为 1 且不能大于总请求次数例如10 个请求10 个并发,实际就是 1 人请求 1 次);</li>
<li>-ppost 参数文档路径(-p 和 -T 参数要配合使用);</li>
<li>-Theader 头内容类型(此处切记是大写英文字母 T</li>
</ul>
<p>当我们测试一个 get 请求接口时,可以直接在链接的后面带上请求的参数:</p>
<pre><code>ab -c 10 -n 100 http://www.test.api.com/test/login?userName=test&amp;password=test
</code></pre>
<p>输出结果如下:</p>
<p><img src="assets/66e7cf2dafa91a3ae80405f97a91899b.png" alt="img" /></p>
<p><strong>以上输出中,有几项性能指标可以提供给你参考使用:</strong></p>
<ul>
<li>Requests per second吞吐率指某个并发用户数下单位时间内处理的请求数</li>
<li>Time per request上面的是用户平均请求等待时间指处理完成所有请求数所花费的时间 /(总请求数 / 并发用户数);</li>
<li>Time per request下面的是服务器平均请求处理时间指处理完成所有请求数所花费的时间 / 总请求数;</li>
<li>Percentage of the requests served within a certain time每秒请求时间分布情况指在整个请求中每个请求的时间长度的分布情况例如有 50% 的请求响应在 8ms 内66% 的请求响应在 10ms 内,说明有 16% 的请求在 8ms~10ms 之间。</li>
</ul>
<h3>2.JMeter</h3>
<p>JMeter 是 Apache 提供的一款功能性比较全的性能测试工具,同样可以在 Windows 和 Linux 环境下安装使用。</p>
<p>JMeter 在 Windows 环境下使用了图形界面,可以通过图形界面来编写测试用例,具有易学和易操作的特点。</p>
<p>JMeter 不仅可以实现简单的并发性能测试,还可以实现复杂的宏基准测试。我们可以通过录制脚本的方式,在 JMeter 实现整个业务流程的测试。JMeter 也支持通过 csv 文件导入参数变量,实现用多样化的参数测试系统性能。</p>
<p>Windows 下的 JMeter 安装非常简单,在官网下载安装包,解压后即可使用。如果你需要打开图形化界面,那就进入到 bin 目录下,找到 jmeter.bat 文件,双击运行该文件就可以了。</p>
<p><img src="assets/2d96660e8e88a2697e066fd301663153.png" alt="img" /></p>
<p>JMeter 的功能非常全面,我在这里简单介绍下如何录制测试脚本,并使用 JMeter 测试业务的性能。</p>
<p>录制 JMeter 脚本的方法有很多,一种是使用 Jmeter 自身的代理录制,另一种是使用 Badboy 这款软件录制,还有一种是我下面要讲的,通过安装浏览器插件的方式实现脚本的录制,这种方式非常简单,不用做任何设置。</p>
<p>首先我们安装一个录制测试脚本的插件,叫做 BlazeMeter 插件。你可以在 Chrome 应用商店中找到它,然后点击安装, 如图所示:</p>
<p><img src="assets/a8f7403c1b6b720318d97accf191843e.png" alt="img" /></p>
<p>然后使用谷歌账号登录这款插件,如果不登录,我们将无法生成 JMeter 文件,安装以及登录成功后的界面如下图所示:</p>
<p><img src="assets/2932afaf9eecb2cce789ad5151180a4a.png" alt="img" /></p>
<p>最后点击开始,就可以录制脚本了。录制成功后,点击保存为 JMX 文件,我们就可以通过 JMeter 打开这个文件,看到录制的脚本了,如下图所示:</p>
<p><img src="assets/bf03e37ace494cf84171b55f9b63bdfd.png" alt="img" /></p>
<p>这个时候,我们还需要创建一个查看结果树,用来可视化查看运行的性能结果集合:</p>
<p><img src="assets/844a2a65add49c2f4d15b10667943069.png" alt="img" /></p>
<p>设置好结果树之后,我们可以对线程组的并发用户数以及循环调用次数进行设置:</p>
<p><img src="assets/431ae410ec4369cc81af7622a23b409b.png" alt="img" /></p>
<p>设置成功之后,点击运行,我们可以看到运行的结果:</p>
<p><img src="assets/6ffe85677e50bb75152d45526a7ba667.png" alt="img" /></p>
<p>JMeter 的测试结果与 ab 的测试结果的指标参数差不多,这里我就不再重复讲解了。</p>
<h3>3.LoadRunner</h3>
<p>LoadRunner 是一款商业版的测试工具,并且 License 的售价不低。</p>
<p>作为一款专业的性能测试工具LoadRunner 在性能压测时,表现得非常稳定和高效。相比 JMeterLoadRunner 可以模拟出不同的内网 IP 地址,通过分配不同的 IP 地址给测试的用户,模拟真实环境下的用户。这里我就不展开详述了。</p>
<h2>总结</h2>
<p>三种常用的性能测试工具就介绍完了,最后我把今天的主要内容为你总结了一张图。</p>
<p><img src="assets/a70d0081607081471df4db435641b51a.jpg" alt="img" /></p>
<p>现在测试工具非常多,包括阿里云的 PTS 测试工具也很好用,但每款测试工具其实都有自己的优缺点。个人建议,还是在熟练掌握其中一款测试工具的前提下,再去探索其他测试工具的使用方法会更好。</p>
</div>
</div>
<div>
<div style="float: left">
<a href="/专栏/Java并发编程实战/加餐 什么是数据的强、弱一致性?.md.html">上一页</a>
</div>
<div style="float: right">
<a href="/专栏/Java并发编程实战/答疑课堂:模块三热点问题解答.md.html">下一页</a>
</div>
</div>
</div>
</div>
</div>
</div>
<a class="off-canvas-overlay" onclick="hide_canvas()"></a>
</div>
<script defer src="https://static.cloudflareinsights.com/beacon.min.js/v652eace1692a40cfa3763df669d7439c1639079717194" integrity="sha512-Gi7xpJR8tSkrpF7aordPZQlW2DLtzUlZcumS8dMQjwDHEnw9I7ZLyiOj/6tZStRBGtGgN6ceN6cMH8z7etPGlw==" data-cf-beacon='{"rayId":"709971c36a8a3d60","version":"2021.12.0","r":1,"token":"1f5d475227ce4f0089a7cff1ab17c0f5","si":100}' crossorigin="anonymous"></script>
</body>
<!-- Global site tag (gtag.js) - Google Analytics -->
<script async src="https://www.googletagmanager.com/gtag/js?id=G-NPSEEVD756"></script>
<script>
window.dataLayer = window.dataLayer || [];
function gtag() {
dataLayer.push(arguments);
}
gtag('js', new Date());
gtag('config', 'G-NPSEEVD756');
var path = window.location.pathname
var cookie = getCookie("lastPath");
console.log(path)
if (path.replace("/", "") === "") {
if (cookie.replace("/", "") !== "") {
console.log(cookie)
document.getElementById("tip").innerHTML = "<a href='" + cookie + "'>跳转到上次进度</a>"
}
} else {
setCookie("lastPath", path)
}
function setCookie(cname, cvalue) {
var d = new Date();
d.setTime(d.getTime() + (180 * 24 * 60 * 60 * 1000));
var expires = "expires=" + d.toGMTString();
document.cookie = cname + "=" + cvalue + "; " + expires + ";path = /";
}
function getCookie(cname) {
var name = cname + "=";
var ca = document.cookie.split(';');
for (var i = 0; i < ca.length; i++) {
var c = ca[i].trim();
if (c.indexOf(name) === 0) return c.substring(name.length, c.length);
}
return "";
}
</script>
</html>