当前位置:网站首页>Stress testing and performance analysis of node projects
Stress testing and performance analysis of node projects
2022-08-02 06:19:00 【Programmer Weizi】
在系统上线前,In order to see how the system can withstand the concurrency and the load condition of concurrent,The round pressure test.在压测过程中,发现服务器的cpuMAO's very high,而tps,接口耗时、Services are available such as are normal,卧槽,这就奇了怪了,You want to along while also didn't figure out why,To turn the bosses,Bosses said check the cpu processor what?这是啥??虽然听不懂,But you can look up╭(╯^╰)╮,But before I found out,Leaders directly to fit,一顿骚操作,Then find out the reason~ It is shame yourself,Internal work enough,Come back online to find the information,Catch up with a handful of how to analyzenodeThe performance problems in engineering.
在开发过程中,Because too focus on the implementation of business logic,Some possible performance is ignored,And these points can only be slightly larger amount of concurrent scenarios will appear,Forget where to see a word 可能会出问题的点,It will be a problem Performance analysis is necessary.
样例项目
为了便于演示,Write a simple little example:
// app.js
const crypto = require('crypto')
const Koa = require('koa')
const Router = require('koa-router');
const app = new Koa();
const router = new Router();
router.get('/crypto', async(ctx, next) => {
const salt = crypto.randomBytes(128).toString('base64')
const hash = crypto.pbkdf2Sync('crypto', salt, 10000, 64, 'sha512').toString('hex')
ctx.body = { hash: hash }
console.log(hash)
ctx.status = 200
next()
});
let reqNum = 0
router.get('/empty', async(ctx, next) => {
ctx.body = { hash: 'empty' }
reqNum++;
ctx.status = 200
next()
});
app.use(router.routes()).use(router.allowedMethods());
app.listen(3000, () => {
console.log("listen 3000")
})
复制代码
基于koa2,有两个路由,一个/crypto,The business logic is,使用cryptoLibrary of string encryption;一个是 /empty,No business logic interface,Is an empty interface.
压力测试
Stress test tool on the market there are many kinds of,就不一一列举了,In the community saw someone recommend autocannon ,Make an introduction to the tool,The official introduction is fast HTTP/1.1 benchmarking tool written in Node.js ,使用node编写的压测工具,能比wrkTo generate more load.
install
npm i autocannon -g
npm i autocannon --save
use
提供两种使用方式:
1. 命令行 autocannon -c 100 -d 5 -p 2 http://127.0.0.1:3000/test 简单快速.
2. api调用 autocannon(opts[, cb]) Easy to write a script.
So a few key parameters are:
-c/--connections NUM 并发连接的数量,默认10.
-p/--pipelining NUM Each connection line request requests.默认1.
-d/--duration SEC 执行的时间,单位秒.
-m/--method METHOD 请求类型 默认GET.
-b/--body BODY 请求报文体.
还有很多参数,You can view the website document.
This library currently only support one interface pressure test,我写了个脚本,Can support batch pressure measurement and generate test report,See the specific code at the end of the article.
report
下图是对 /empty 接口压测 autocannon -c 100 -d 5 -p 1 http://127.0.0.1:3000/empty 结果如下:
可看到,每秒有100个链接,Each link a request,持续5秒,一共产生 31k 次请求.
报告分三部分,The first line says the delay of the interface,The second line indicates the number of requests per second(tps),The third line said returns number of bytes per second.那么,延迟越低,tps越高,It means the better the performance of interface,因为empty 是个空接口,所以它的tps=6221还不错,Response time is also very soon,我们换成 /crypto Interface in a try.
Immediately see the gap between,这个接口tps只有77,Interface takes to1100ms,Indicates that the interface has a lot of optimization space.
Generates performance file and analysis
Through pressure measurement tools we found defective interface,那接下来,Is going to analyzes the interface,But at the interface code,不好分析啊,After all, no convincing,We need a performance report,用数据说话,Here are the two methods for everyone.
V8 Profiler
V8 The official has been considering this for you,提供了Profiler工具 Use is also very quick,步骤如下.以app.js为例)
生成报告
在启动命令中加上 --prof ,如 node --prof app.js ,在项目根目录会生成isolate-xxxxxxx-v8.log格式的文件,Used to record information such as the call stack and time during running,其中内容如下.(文件较大,Will capture the top a bit)
v8-version,6,1,534,47,0
shared-library,"C:\Program Files\nodejs\node.exe",0x7ff7505f0000,0x7ff751c0f000,0
shared-library,"C:\WINDOWS\SYSTEM32\ntdll.dll",0x7ff8718a0000,0x7ff871a61000,0
shared-library,"C:\WINDOWS\system32\KERNEL32.DLL",0x7ff870590000,0x7ff87063d000,0
shared-library,"C:\WINDOWS\system32\KERNELBASE.dll",0x7ff86e830000,0x7ff86ea18000,0
shared-library,"C:\WINDOWS\system32\WS2_32.dll",0x7ff86ee00000,0x7ff86ee6b000,0
分析报告
对刚刚生成的log文件分析,Or using official tools node --prof-process isolate-xxxxxxxx-v8.log,生成结果如下.(Remove the useless part)
Statistical profiling result from isolate-00000209B99A60A0-v8.log, (17704 ticks, 8 unaccounted, 0 excluded).
[Shared libraries]:
ticks total nonlib name
13795 77.9% C:\WINDOWS\SYSTEM32\ntdll.dll
...
[JavaScript]:
ticks total nonlib name
12 0.1% 11.3% Builtin: CallFunction_ReceiverIsAny
...
[C++]:
ticks total nonlib name
[Summary]:
ticks total nonlib name
94 0.5% 88.7% JavaScript
0 0.0% 0.0% C++
8 0.0% 7.5% GC
17598 99.4% Shared libraries
8 0.0% Unaccounted
[C++ entry points]:
ticks cpp total name
[Bottom up (heavy) profile]:
Note: percentage shows a share of a particular caller in the total
amount of its parent calls.
Callers occupying less than 1.0% are not shown.
ticks parent name
13795 77.9% C:\WINDOWS\SYSTEM32\ntdll.dll
3795 21.4% C:\Program Files\nodejs\node.exe
3768 99.3% C:\Program Files\nodejs\node.exe
3287 87.2% Function: ~pbkdf2 crypto.js:633:16
3287 100.0% Function: ~exports.pbkdf2Sync crypto.js:628:30
3287 100.0% Function: ~router.get D:\github\webapp\js\usen\app.js:8:23
3287 100.0% Function: ~dispatch D:\github\webapp\js\usen\node_modules\[email protected]@koa-compose\index.js:37:23
...
The report contains six parts:Shared libraries、JavaScript、C++、Summary、C++ entry points 和 Bottom up (heavy) profile,[JavaScript] 部分列出了 JavaScript Code execution occupied CPU ticks(CPU 时钟周期),[C++] 部分列出了 C++ Code execution occupied CPU ticks,[Summary] Lists the various parts of,[Bottom up] 列出了所有 CPU Elapsed time from large to small function and stack information.
根据 3287 87.2% Function: ~pbkdf2 crypto.js:633:16 We can see the function cost 87.2% 的cpu.
File is not intuitive,那我们换个UI界面的,步骤如下:
·先clone v8The warehouse down git clone GitHub - v8/v8: The official mirror of the V8 Git repository
· The log file is converted into json格式 node --prof-process --preprocess isolate-xxxxxxxxxx-v8.log > v8.json
· 打开 v8/tools/profview/index.html 文件,Is a static interface,In the center of the interface to choose just generated v8.json文件,After the success of the file parsing,界面如下:
Specific function not explain one,We drill-down,Looking for time-consuming point,Soon find consumptioncpu的地方,如下图:
node占比是45%,其中 pbkdf2 crypto.js便占用了92%.
v8-profiler
In addition to the official offer,We can also choose to open source the library of,v8-profiler ,This library to create an earlier time,6Years ago he created,More recently as a year and a half ago,Community assessment is good.
生成报告
Generation is simple,不足的是,Need to hard code in the project,如下:
profiler.startProfiling('', true);
setTimeout(function() {
var profile = profiler.stopProfiling('');
profile.export()
.pipe(fs.createWriteStream(`cpuprofile-${Date.now()}.cpuprofile`))
.on('finish', () => profile.delete())
}, 1000);
解析报告
·Chrome
我们的大ChromeTo be a horse,在Chrome的控制台,有一栏 JavaScript Profile 如下图:
点击load,Select just the generated files,Resolved as follows:
逐层查看,Then know.
· flamegraph-火焰图
使用 flamegraph Generate cool flame figure,With a force in the report that is cool,官网图如下:
Use will not dwell on.
· v8-analytics
This is a community leaders,Write a open source library v8-analytics,官方介绍如下
解析v8-profiler和heapdumpA tool such as the output ofcpu & heap-memory日志,可以提供:
1)v8Inverse optimization engine or the red show failure function and optimize the reasons for failure to show;
2)Function performs the length more than expected standard red show;
3)Suspicious of memory leak point in the current project show.
对应的命令如下:
va test bailout --only This command can only take thosev8Engine inverse optimization functions listed show.
va test timeout 200 --only This command can only put those holding over200msThe function of listed show.
va test leak Suspicious reveal a testheapsnapshotFile suspicious of memory leak point.
The benefits of this library are,It opens at province we one by one to find,Screening questions so that we can more convenient to us~
Batch tests and generate a report
autocannon Can only run one interface,To test the next interface,就得修改代码,Such as to batch test multiple interfaces,Just need to change the code back and forth,操作就比较麻烦,所以我基于 autocannon 写了个脚本,Can one by one, pressure measurement YiHaoDe interface,At the same time can also generate test report.
'use strict'
const autocannon = require('autocannon')
const reporter = require('autocannon-reporter')
const path = require('path')
const sleep = ms => new Promise(resolve => setTimeout(resolve, ms));
/**
* @description
* 运行autocannon
* [url=home.php?mod=space&uid=267564]@Author[/url] lizc
* @param {*} param
*/
function makeAutocannon(param) {
autocannon(param).on('done', handleResults)
}
/**
* @description
* 处理接口
* @author lizc
* @param {*} result
*/
function handleResults(result) {
const reportOutputPath = path.join(`./${result.title}_report.html`)
reporter.writeReport(reporter.buildReport(result), reportOutputPath, (err, res) => {
if (err) console.err('Error writting report: ', err)
else console.log('Report written to: ', reportOutputPath)
})
}
// 请求参数
const autocannonParam = {
url: 'http://127.0.0.1:6100/',
connections: 100,
duration: 10,
headers: {
type: 'application/x-www-form-urlencoded'
}
}
// 请求报文参数
const requestsParam = {
method: 'POST', // this should be a put for modifying secret details
headers: { // let submit some json?
'Content-type': 'application/json; charset=utf-8'
}
}
/**
* @description
* Start the batch pressure test
* @author lizc
* @param {*} methodList 接口列表
*/
async function run(methodList) {
const autocannonList = methodList.map(val => {
return {
...autocannonParam,
url: autocannonParam.url + val,
title: val,
requests: [
{
...requestsParam,
}
],
}
})
for (let i = 0; i < autocannonList.length; i++) {
if (i !== 0) {
await sleep((autocannonList[i - 1].duration + 2) * 1000)
makeAutocannon(autocannonList[i])
} else {
makeAutocannon(autocannonList[i])
}
}
}
// 启动
run(['order', 'crypto'])
最后感谢每一个认真阅读我文章的人,礼尚往来总是要有的,虽然不是什么很值钱的东西,如果你用得到的话可以直接拿走:938856006资料在裙里,需要可以自取
这些资料,对于【软件测试】的朋友来说应该是最全面最完整的备战仓库,这个仓库也陪伴上万个测试工程师们走过最艰难的路程,希望也能帮助到你!
既然都看到这里啦,请你帮个忙:
1、点赞,让更多小伙伴看到;
2、关注我,持续更新测试干货.
边栏推荐
- How Navicat Connects to MySQL
- ApiPost 真香真强大,是时候丢掉 Postman、Swagger 了
- Detailed explanation of the software testing process (mind map) of the first-tier manufacturers
- MySql将一张表的数据copy到另一张表中
- JDBC revisited
- LeetCode刷题系列 -- 787. K 站中转内最便宜的航班
- Detailed explanation of AMQP protocol
- Navicat如何连接MySQL
- Matlab paper illustration drawing template No. 41 - bubble chart (bubblechart)
- How much does a test environment cost? Start with cost and efficiency
猜你喜欢
利用浏览器本地存储 实现记住用户名的功能
What do interview test engineers usually ask?The test supervisor tells you
Detailed explanation of mysql stored procedure
100 latest software testing interview questions in 2022, summary of common interview questions and answers
How much does a test environment cost? Start with cost and efficiency
nacos注册中心
mysql安装教程【安装版】
软件测试的需求人才越来越多,为什么大家还是不太愿意走软件测试的道路?
MySQL 多表关联一对多查询实现取最新一条数据
Matlab论文插图绘制模板第41期—气泡图(bubblechart)
随机推荐
Detailed explanation of mysql stored procedure
2022年100道最新软件测试面试题,常见面试题及答案汇总
Use the browser's local storage to realize the function of remembering the user name
Detailed explanation of AMQP protocol
golang generics
MySQL 8.0.28 version installation and configuration method graphic tutorial
[PSQL] 窗口函数、GROUPING运算符
构造方法、成员变量、局部变量
Detailed installation and configuration of golang environment
C语言入门实战(13):十进制数转二进制
Detailed explanation of interface in Go language
MySQL String Concatenation - Various String Concatenation Practical Cases
Redis集群模式
C语言中i++和++i在循环中的差异性
navicat连接MySQL报错:1045 - Access denied for user ‘root‘@‘localhost‘ (using password YES)
leetcode 665. Non-decreasing Array 非递减数列(中等)
【C语言】LeetCode26.删除有序数组中的重复项&&LeetCode88.合并两个有序数组
Google Chrome(谷歌浏览器)安装使用
ATM系统
interrupt()、interrupted()和isInterrupted()你真的懂了吗