当前位置:网站首页>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、关注我,持续更新测试干货.
边栏推荐
猜你喜欢

MySQL 8.0.29 设置和修改默认密码

Google 安装印象笔记剪藏插件

MySQL multi-table association one-to-many query to get the latest data

JUC(二)原子类:CAS、乐观锁、Unsafe和原子类

MySQL implements sorting according to custom (specified order)

25K测试老鸟6年经验的面试心得,四种公司、四种问题…

ERROR 1045 (28000) Access denied for user ‘root‘@‘localhost‘解决方法

MySql copies data from one table to another table

测试环境要多少?从成本与效率说起
![[PSQL] 窗口函数、GROUPING运算符](/img/95/5c9dc06539330db907d22f84544370.png)
[PSQL] 窗口函数、GROUPING运算符
随机推荐
CPU使用率和负载区别及分析
MySQL 8.0.29 decompressed version installation tutorial (valid for personal testing)
Google Chrome(谷歌浏览器)安装使用
构造方法、成员变量、局部变量
面试测试工程师一般会问什么?测试主管告诉你
ELK日志分析系统
C语言小游戏——扫雷小游戏
The company does not pay attention to software testing, and the new Ali P8 has written a test case writing specification for us
提高软件测试能力的方法有哪些?看完这篇文章让你提升一个档次
LeetCode刷题系列 -- 787. K 站中转内最便宜的航班
Detailed explanation of interface in Go language
Packaging and deployment of go projects
浏览器的onload事件
swinIR论文阅读笔记
非关系型数据库MongoDB的特点及安装
golang's time package: methods for time interval formatting and output of timestamp formats such as seconds, milliseconds, and nanoseconds
Three methods of importing sql files in MySQL
golang泛型
网安学习-内网渗透4
Introduction and use of apifox (1).