前言
因为最近学习需要用到一些测试库测试性能,但是工具又太复杂不好用,恰好发现有这么一个库用法输出都很近似,可惜没有找到有中文版或者用法笔记,所以只好耐心一点一点翻译出来。因为我的英文水平很一般,而这种技术博客直接机翻是表达不出意思的,只能硬着头皮按自己理解写出来,为了不误人误己,我在原文底下翻译,这样大家也可以直接看原文。
全文加起来一万八字,原文大概就九千字吧,如果嫌界面排版难看的直接去原文吧。
loadtest
有些地方真的不知道怎么翻译,有能力的麻烦指正一下。
loadtest
Runs a load test on the selected HTTP or WebSockets URL. The API allows for easy integration in your own tests.
在选定的 HTTP 或者 WebSockets URL 上进行负载测试,API 允许在你自己的测试里轻松集成。
Installation
Install globally as root:
全局安装
# npm install -g loadtest
On Ubuntu or Mac OS X systems install using sudo:
在 Ubuntu 或者 Mac OS X 系统安装使用 sudo
$ sudo npm install -g loadtest
For access to the API just add package
loadtest
to yourpackage.json
devDependencies:
想要访问 API 只需要在 package.json
里的 devDependencies
添加loadtest
{
...
"devDependencies": {"loadtest": "*"},
...
}
用法
Why use
loadtest
instead of any other of the available tools, notably Apacheab
?loadtest
allows you to configure and tweak requests to simulate real world loads.
为什么使用 loadtest 替代其他的可用工具,尤其是 Apache ab
?loadtest
允许你配置和调整请求去模拟真实世界的负载。
基础用法
Run as a script to load test a URL:
作为脚本执行去负载测试 URL:
$ loadtest [-n requests] [-c concurrency] [-k] URL
The URL can be “http://”, “https://” or “ws://”.
Set the max number of requests with-n
, and the desired level of concurrency with the-c
parameter.
Use keep-alive connections with-k
whenever it makes sense,
which should be always except when you are testing opening and closing connections.
URL 可以是 ”http://”, “https://” 或者 “ws://”.-n
设置最大请求数,-c
设置并发级别,
除了测试打开和关闭连接以外有意义的时候可以用 -k
做长连接。
Single-dash parameters (e.g.
-n
) are designed to be compatible with
Apacheab
,
except that here you can add the parameters after the URL.
单破折号参数(例如-n
)被设计为可兼容 Apache ab
,除了你可以在 URL 后面添加参数。
To get online help, run loadtest without parameters:
想要获取线上帮助,运行 loadtest 不带参数:
$ loadtest
用法文档
The set of basic options are designed to be compatible with Apache
ab
.
But whileab
can only set a concurrency level and lets the server adjust to it,loadtest
allows you to set a rate or requests per second with the--rps
option.
基本设置选项被设计为可兼容 Apache ab
,然而 ab
只能设置并发级别让服务端调整它。loadtest
允许你用 --rps
选项设置每秒速率或请求数(后面统称 rps)。
Example:
loadtest -c 10 --rps 200 http://mysite.com/
This command sends exactly 200 requests per second with concurrency 10, so you can see how your server copes with sustained rps. Even if ab reported a rate of 200 rps, you will be surprised to see how a constant rate of requests per second affects performance: no longer are the requests adjusted to the server, but the server must adjust to the requests! Rps rates are usually lowered dramatically, at least 20~25% (in our example from 200 to 150 rps), but the resulting figure is much more robust.
这个命令在 10 并发量情况下每秒发送 200 个请求,所以你能看到你的服务端怎么处理持续的 rps。即使是 ab
报告的速率是 200rps,你也会惊奇地看到每秒请求的恒定速率怎么影响性能;不再调整请求到服务器,但是服务器必须调整到请求! Rps 率通常会大幅降低至少 20~25%(在我们的例子 200-150rps),但由此得出的数据要稳健得多。
(有点绕,不知道怎么翻)
loadtest
is also quite extensible. Using the provided API it is very easy to integrate loadtest with your package, and run programmatic load tests. loadtest makes it very easy to run load tests as part of systems tests, before deploying a new version of your software. The results include mean response times and percentiles, so that you can abort deployment e.g. if 99% of the requests don’t finish in 10 ms or less.
loadtest
是可扩展的。使用提供的 API 非常容易整合 loadtest 到你的包里进行编程负载测试。在部署新版本软件之前,loadtest 使运行负载测试成为系统测试的一部分变得非常容易。
结果包括平均响应时间和百分比,以便你可以终止部署,例如,如果 99% 的请求在 10 毫秒或更短的时间内没有完成。
注意事项
loadtest
saturates a single CPU pretty quickly.
Do not useloadtest
if the Node.js process is above 100% usage intop
, which happens approx. when your load is above 1000~4000 rps.
(You can measure the practical limits ofloadtest
on your specific test machines by running it against a simple
Apache or nginx process and seeing when it reaches 100% CPU.)
loadtest
会很快使单个 CPU 饱和。
如果 Node.js 使用率已经超过 100% 不要使用 loadtest
,当你负载超过 1000~4000rps 会发生类似的事。
(你可以运行指定的测试机器测量loadtest
的实际极限通过简单的 Apache 或者 nginx 进程查看什么时候达到 100%CPU。
There are better tools for that use case:
这些是使用示例更好的工具
-
Apache
ab
has great performance, but it is also limited by a single CPU performance.Its practical limit is somewhere around ~40 krps. -
weighttp is also
ab
-compatible and is supposed to be very fast (the author has not personally used it). -
wrk is multithreaded and fit for use when multiple CPUs are required or available.It may need installing from source though, and its interface is not
ab
-compatible. - ab 性能优异,但是总是受限于单个 CPU 性能,它的实际极限大概 40krps。
- weighttp 可以兼容
ab
并且快速支持(作者没有用过) -
wrk 是多线程的,适合在需要或可用多个 cpu 时使用,它可能需要安装源文件并且不兼容
ab
。
常规用法
The following parameters are compatible with Apache ab.
下面参数兼容 Apache ab.
-n requests
Number of requests to send out.
发送请求数量
Note: the total number of requests sent can be bigger than the parameter if there is a concurrency parameter;loadtest will report just the first
n
.
注意: 如果有并发参数,发送的请求总数可以大于参数;loadtest 将只报告第一个n
。
(我猜这里意思是前一个 n 也就是发送的请求总数)
-c concurrency
loadtest will create a certain number of clients; this parameter controls how many.
Requests from them will arrive concurrently to the server.
loadtest 会创建一定数量的客户端,这参数控制具体多少。
它们的请求会并发到达服务端。
Note: requests are not sent in parallel (from different processes),
but concurrently (a second request may be sent before the first has been answered).
注意:请求实际上没有并行发送(来自不同的进程),
但是并发(第二个请求在第一个请求响应之前发送)
(并行是指两个或者多个事件在同一时刻发生;而并发是指两个或多个事件在同一时间间隔发生,同时与交替的区别。)
-t timelimit
Max number of seconds to wait until requests no longer go out.
等待直到请求不再发送的时间
Note: this is different than Apache
ab
, which stops receiving requests after the given seconds.
注意:这里不同于ab
,后者会在给定时间后停止接收请求。
-k
or --keepalive
Open connections using keep-alive: use header ‘Connection: Keep-alive’ instead of ‘Connection: Close’.
使用 keepalive 打开连接,使用请求头 ‘Connection: Keep-alive’ instead of ‘Connection: Close’.
Note: Uses agentkeepalive,
which performs better than the default node.js agent.
注意:使用 agentkeepalive 会好过默认的 node.js 代理。
-C cookie-name=value
Send a cookie with the request. The cookie
name=value
is then sent to the server.
This parameter can be repeated as many times as needed.
发送请求 cookie,name=value
会被发送到服务端。
这个参数能够根据需要重复使用。
-H header:value
Send a custom header with the request. The line
header:value
is then sent to the server.
This parameter can be repeated as many times as needed.
发送自定义请求头的请求,这行的 header:value
会被发送到服务端。
这个参数能够重复多次使用。
Example:
$ loadtest -H user-agent:tester/0.4 ...
Note: if not present, loadtest will add a few headers on its own: the “host” header parsed from the URL,
a custom user agent “loadtest/” plus version (loadtest/1.1.0
), and an accept header for “*/*”.
注意:如果不存在,loadtest 会附加一些自己的头信息。从 URL 解析出来的“host”头,一个自定义的用户代理 ”loadtest/” 附加版本(loadtest/1.1.0
),可接受 ”*/*” 头。
Note: when the same header is sent several times, only the last value will be considered.
If you want to send multiple values with a header, separate them with semicolons:
注意:当同一个请求头发送给服务端几次,只有最后的值会被考虑。
如果你想一个请求头发送多个值,使用分号分割。
$ loadtest -H accept:text/plain;text-html ...
Note: if you need to add a header with spaces, be sure to surround both header and value with quotes:
注意:如果你需要添加空格头,确保引号包裹着头和值两端;
$ loadtest -H "Authorization: Basic xxx=="
-T content-type
Set the MIME content type for POST data. Default:
text/plain
.
设置 POST 提交数据的 MIME 内容类型,默认: text/plain
.
-P POST-body
Send the string as the POST body. E.g.:
-P '{"key":"a9acf03f"}'
发送一段字符串作为 POST 请求体,例如: -P '{"key":"a9acf03f"}'
-A PATCH-body
Send the string as the PATCH body. E.g.:
-A '{"key":"a9acf03f"}'
发送一段字符串作为 PATCH 请求体,例如: -A '{"key":"a9acf03f"}'
-m method
Send method to link. Accept: [GET, POST, PUT, DELETE, PATCH, get, post, put, delete, patch], Default is GET,E.g.: -m POST
发送到链接的方法。可接受[GET, POST, PUT, DELETE, PATCH, get, post, put, delete, patch],默认是 GET,例如:-m POST
--data POST some variables
Send some data. It does not support method GET. E.g: –data ‘{“username”: “test”, “password”: “test”}’ -T ‘application/x-www-form-urlencoded’ -m POST
It required -m and -T ‘application/x-www-form-urlencoded’
发送一些数据,不支持方法 GET
E.g: --data '{"username":"test","password":"test"}' -T 'application/x-www-form-urlencoded' -m POST
它需要 -m and -T ‘application/x-www-form-urlencoded’
-p POST-file
Send the data contained in the given file in the POST body.
Remember to set-T
to the correct content-type.
发送被包含在给定文件的 POST 请求体的数据。
记住设置给-T
正确的内容类型。
If
POST-file
has.js
extension it will berequire
d. It should be a valid node module and it
shouldexport
a single function, which is invoked with an automatically generated request identifier
to provide the body of each request.
This is useful if you want to generate request bodies dynamically and vary them for each request.
如果 POST-file
有 .js
扩展名会被引入,它应该是一个有效的 Node 模块并且导出单个使用自动生成的请求标识符调用提供每个请求的主体的函数。如果你想要动态生成请求并且改变它们的每一个这非常有用。
(有点拗口,不知道翻译对不对)
Example:
module.exports = function(requestId) {
// this object will be serialized to JSON and sent in the body of the request
return {
key: 'value',
requestId: requestId
};
};
-u PUT-file
Send the data contained in the given file as a PUT request.
Remember to set-T
to the correct content-type.
发送被包含在给定文件的 PUT 请求体的数据。
记住设置给-T
正确的内容类型。
If
PUT-file
has.js
extension it will berequire
d. It should be a valid node module and it
shouldexport
a single function, which is invoked with an automatically generated request identifier
to provide the body of each request.
This is useful if you want to generate request bodies dynamically and vary them for each request.
For an example function see above for-p
.
如果 PUT-file
有 .js
扩展名会被引入,它应该是一个有效的 Node 模块并且导出单个使用自动生成的请求标识符调用提供每个请求的主体的函数。如果你想要动态生成请求并且改变它们的每一个这非常有用。
示例函数请参见上面的 -p
。
-a PATCH-file
Send the data contained in the given file as a PATCH request.
Remember to set-T
to the correct content-type.
发送被包含在给定文件的 PATCH 请求体的数据。
记住设置给-T
正确的内容类型。
If
PATCH-file
has.js
extension it will berequire
d. It should be a valid node module and it
shouldexport
a single function, which is invoked with an automatically generated request identifier
to provide the body of each request.
This is useful if you want to generate request bodies dynamically and vary them for each request.
For an example function see above for-p
.
如果 PATCH-file
有 .js
扩展名会被引入,它应该是一个有效的 Node 模块并且导出单个使用自动生成的请求标识符调用提供每个请求的主体的函数。如果你想要动态生成请求并且改变它们的每一个这非常有用。
示例函数请参见上面的 -p
。
-r
Recover from errors. Always active: loadtest does not stop on errors.
After the tests are finished, if there were errors a report with all error codes will be shown.
从错误中恢复,总是处于活跃之中:loadtest 不会因为错误而停止。
在测试完成之后,如果出现错误,将显示一个包含所有错误码的报告。
-s
The TLS/SSL method to use. (e.g. TLSv1_method)
使用 TLS/SSL 方法,(例如 TLSv1_method)
Example:
$ loadtest -n 1000 -s TLSv1_method https://www.example.com
-V
Show version number and exit.
显示版本号并且退出
Advanced Usage
The following parameters are not compatible with Apache ab.
下面参数并不兼容 Apache ab.
--rps requestsPerSecond
Controls the number of requests per second that are sent.
Can be fractional, e.g.--rps 0.5
sends one request every two seconds.
控制每秒发送请求的数量。
可以是小数,例如--rps 0.5
两秒发送一个请求。
Note: Concurrency doesn’t affect the final number of requests per second,
since rps will be shared by all the clients. E.g.:
注意:并发性不影响最终每秒发送的请求数,
因为 rps 会被所有客户端共享,例如
loadtest <url> -c 10 --rps 10
will send a total of 10 rps to the given URL, from 10 different clients
(each client will send 1 request per second).
会从 10 个不同的客户端向给定的 URL 发送总共 10rps(每个客户端将每秒发送一个请求)
Beware: if concurrency is too low then it is possible that there will not be enough clients
to send all of the rps, adjust it with-c
if needed.
注意:如果并发太低可能会导致没有足够的客户端发送所有的 rps,需要的话可以使用 -c
调整。
Note: –rps is not supported for websockets.
注意:–rps 不支持 websockets
--timeout milliseconds
Timeout for each generated request in milliseconds.
Setting this to 0 disables timeout (default).
每个生成请求的超时时间为毫秒
设置为 0 禁止超时(默认)
-R requestGeneratorModule.js
Use custom request generator function from an external file.
使用外部文件的自定义请求生成函数
Example request generator module could look like this:
外部文件的自定义请求生成函数可能如下:
module.exports = function(params, options, client, callback) {generateMessageAsync(function(message) {if (message)
{options.headers['Content-Length'] = message.length;
options.headers['Content-Type'] = 'application/x-www-form-urlencoded';
}
request = client(options, callback);
if (message){request.write(message);
}
return request;
}
}
See
sample/request-generator.js
for some sample code including a body.
查看 sample/request-generator.js
一些包括主体的示例代码
--agent
(deprecated)
Open connections using keep-alive.
使用长连接打开
Note: instead of using the default agent, this option is now an alias for
-k
.
注意: 这个选项不是使用默认代理,而是 -k
的别名。
--quiet
Do not show any messages.
不展示任何信息
--debug
Show debug messages.
展示 debug 信息
--insecure
Allow invalid and self-signed certificates over https.
允许无效和自签名证书通过 https。
--cert path/to/cert.pem
Sets the certificate for the http client to use. Must be used with
--key
.
设置 http 客户端使用的证书,必须使用--key
.
--key path/to/key.pem
Sets the key for the http client to use. Must be used with
--cert
.
设置 http 客户端使用的 key,必须使用--cert
.
Server
loadtest bundles a test server. To run it:
loadtest 捆绑一个测试服务器,运行:
$ testserver-loadtest [--delay ms] [error 5xx] [percent yy] [port]
This command will show the number of requests received per second,
the latency in answering requests and the headers for selected requests.
这个命令将显示每秒接收的请求数,响应请求延迟和所选请求头。
The server returns a short text ‘OK’ for every request,
so that latency measurements don’t have to take into account request processing.
服务器会为每个请求返回短文 OK
。
所以延迟测量不需要考虑处理请求。
If no port is given then default port 7357 will be used.
The optional delay instructs the server to wait for the given number of milliseconds
before answering each request, to simulate a busy server.
You can also simulate errors on a given percent of requests.
如果没有给定端口会默认使用 7357.
延迟可选项命令服务器在每个请求响应之前等待给定的毫秒数模拟繁忙的服务器。你可以在给定的请求百分比中模拟错误。
Complete Example
Let us now see how to measure the performance of the test server.
让我们看看怎么测量测试服务器的性能
First we install
loadtest
globally:
首先全局安装 loadtest
$ sudo npm install -g loadtest
Now we start the test server:
现在我们开启测试服务器
$ testserver-loadtest
Listening on port 7357
On a different console window we run a load test against it for 20 seconds
with concurrency 10 (only relevant results are shown):
在不同的控制台窗口我们靠它运行负载测试在 20 秒内并发量 10(只有相关结果会展示)
$ loadtest http://localhost:7357/ -t 20 -c 10
...
Requests: 9589, requests per second: 1915, mean latency: 10 ms
Requests: 16375, requests per second: 1359, mean latency: 10 ms
Requests: 16375, requests per second: 0, mean latency: 0 ms
...
Completed requests: 16376
Requests per second: 368
Total time: 44.503181166000005 s
Percentage of the requests served within a certain time
50% 4 ms
90% 5 ms
95% 6 ms
99% 14 ms
100% 35997 ms (longest request)
Results were quite erratic, with some requests taking up to 36 seconds;
this suggests that Node.js is queueing some requests for a long time, and answering them irregularly.
Now we will try a fixed rate of 1000 rps:
结果相当不稳定,有些请求占用了 36 秒;
这暗示 Nodejs 很长一段时间内都在排列一些请求然后不定期响应它们。
现在我们尝试 1000rps 的固定速率。
$ loadtest http://localhost:7357/ -t 20 -c 10 --rps 1000
...
Requests: 4551, requests per second: 910, mean latency: 0 ms
Requests: 9546, requests per second: 1000, mean latency: 0 ms
Requests: 14549, requests per second: 1000, mean latency: 20 ms
...
Percentage of the requests served within a certain time
50% 1 ms
90% 2 ms
95% 8 ms
99% 133 ms
100% 1246 ms (longest request)
Again erratic results. In fact if we leave the test running for 50 seconds we start seeing errors:
再次不稳定,事实上如果我们让测试运行 50 秒,我们就会看到错误。
$ loadtest http://localhost:7357/ -t 50 -c 10 --rps 1000
...
Requests: 29212, requests per second: 496, mean latency: 14500 ms
Errors: 426, accumulated errors: 428, 1.5% of total requests
Let us lower the rate to 500 rps:
让我们低于 500rps 运行看看
$ loadtest http://localhost:7357/ -t 20 -c 10 --rps 500
...
Requests: 0, requests per second: 0, mean latency: 0 ms
Requests: 2258, requests per second: 452, mean latency: 0 ms
Requests: 4757, requests per second: 500, mean latency: 0 ms
Requests: 7258, requests per second: 500, mean latency: 0 ms
Requests: 9757, requests per second: 500, mean latency: 0 ms
...
Requests per second: 500
Completed requests: 9758
Total errors: 0
Total time: 20.002735398000002 s
Requests per second: 488
Total time: 20.002735398000002 s
Percentage of the requests served within a certain time
50% 1 ms
90% 1 ms
95% 1 ms
99% 14 ms
100% 148 ms (longest request)
Much better: a sustained rate of 500 rps is seen most of the time,
488 rps average, and 99% of requests answered within 14 ms.
好很多了:能看到大多数时间都持续在 500rps 速率,平均 488rps 和 99% 请求响应在 14 毫秒内。
We now know that our server can accept 500 rps without problems.
Not bad for a single-process naïve Node.js server…
We may refine our results further to find at which point from 500 to 1000 rps our server breaks down.
我们现在知道我们的服务器在 500rps 内没有问题。
对一个单进程纯 Node.js 服务器来说不差。。。
我们可以进一步改进我们的结果,以发现我们的服务器从 500 到 1000 rps 在哪个点崩溃。
But instead let us research how to improve the results.
One obvious candidate is to add keep-alive to the requests so we don’t have to create
a new connection for every request.
The results (with the same test server) are impressive:
但是,让我们研究一下如何改进结果。
一个明显的后备方案是添加长连接请求让我们不需要为每个请求创建新的连接。
结果(同一个测试服务器)感人。
$ loadtest http://localhost:7357/ -t 20 -c 10 -k
...
Requests per second: 4099
Percentage of the requests served within a certain time
50% 2 ms
90% 3 ms
95% 3 ms
99% 10 ms
100% 25 ms (longest request)
Now you’re talking! The steady rate also goes up to 2 krps:
现在你们可以说,这稳定比率总是达到 2rps;
$ loadtest http://localhost:7357/ -t 20 -c 10 --keepalive --rps 2000
...
Requests per second: 1950
Percentage of the requests served within a certain time
50% 1 ms
90% 2 ms
95% 2 ms
99% 7 ms
100% 20 ms (longest request)
Not bad at all: 2 krps with a single core, sustained.
However, it you try to push it beyond that, at 3 krps it will fail miserably.
一点也不差:单核 2krps,稳定。
然而,如果你试图推上 3krps 会失败地很惨。
API
loadtest
is not limited to running from the command line; it can be controlled using an API,
thus allowing you to load test your application in your own tests.
loadtest
不限于从命令行运行;它能够使用 API 控制,因此允许你在自己的测试里去负载测试你的应用程序。
执行负载测试
To run a load test, just call the exported function
loadTest()
with a set of options and an optional callback:
运行负载测试,只要设置一些可选项和可选回调函数调用导出函数loadTest()
:
const loadtest = require('loadtest');
const options = {
url: 'http://localhost:8000',
maxRequests: 1000,
};
loadtest.loadTest(options, function(error, result)
{if (error)
{return console.error('Got an error: %s', error);
}
console.log('Tests run successfully');
});
The callback
function(error, result)
will be invoked when the max number of requests is reached,or when the max number of seconds has elapsed.
当最大请求数已经达到或者当秒数超过最大值之后回调函数 function(error, result)
会被执行。
Beware: if there are no
maxRequests
and nomaxSeconds
, then tests will run forever and will not call the callback.
注意:如果没有maxRequests
和 maxSeconds
,测试会一直运行不执行回调。
Options
All options but
url
are, as their name implies, optional.
除了 url 以外所有可选项,顾名思义都是可选
url
The URL to invoke. Mandatory.
要调用的 URL,必须
concurrency
How many clients to start in parallel.
客户端并行启动数量。
maxRequests
A max number of requests; after they are reached the test will end.
请求最大量;当达到之后测试会结束
Note: the actual number of requests sent can be bigger if there is a concurrency level;
loadtest will report just on the max number of requests.
注意:如果是并发级别实际发送请求数量更加大;loadtest 只会报出请求最大量。
maxSeconds
Max number of seconds to run the tests.
运行测试的最大秒数。
Note: after the given number of seconds
loadtest
will stop sending requests,
but may continue receiving tests afterwards.
注意:loadtest 会在给定的秒数之后停止发送请求,但之后可能会继续接受测试。
timeout
Timeout for each generated request in milliseconds. Setting this to 0 disables timeout (default).
每个生成请求的超时时间,0 为禁止超时(默认)。
cookies
An array of cookies to send. Each cookie should be a string of the form name=value.
发送一组 cookies,每个 cookie 应该是表单名称 = 值的字符串。
headers
A map of headers. Each header should be an entry in the map with the value given as a string.
If you want to have several values for a header, write a single value separated by semicolons,
like this:
请求头映射,每个请求头应该是映射的一个条目,其值是字符串输出。如果你想要有一个条目多个值,使用分号切割:
{accept: "text/plain;text/html"}
Note: when using the API, the “host” header is not inferred from the URL but needs to be sent explicitly.
注意:当使用 API,”host” 不会从 URL 推导出来,需要明确传输过来。
method
The method to use: POST, PUT. Default: GET.
使用方法 POST, PUT,默认 GET。
body
The contents to send in the body of the message, for POST or PUT requests.
Can be a string or an object (which will be converted to JSON).
在消息体中发送的内容,用于 POST 或 PUT 请求。可以是字符串或者对象(需要转译成 JSON)
contentType
The MIME type to use for the body. Default content type is
text/plain
.
请求体使用的 MIME 类型,默认text/plain
.
requestsPerSecond
How many requests each client will send per second.
每个客户端每秒发送多少请求
requestGenerator
Custom request generator function.
自定义请求生成函数。
Example request generator function could look like this:
自定义请求生成器函数可能如下:
function(params, options, client, callback) {generateMessageAsync(function(message)) {request = client(options, callback);
if (message)
{options.headers['Content-Length'] = message.length;
options.headers['Content-Type'] = 'application/x-www-form-urlencoded';
request.write(message);
}
request.end();}
}
agentKeepAlive
Use an agent with ‘Connection: Keep-alive’.
使用 Connection: Keep-alive
代理
Note: Uses agentkeepalive,
which performs better than the default node.js agent.
注意:使用 agentkeepalive 性能更加优异于默认 nodejs 代理。
quiet
Do not show any messages.
不显示任何信息
indexParam
The given string will be replaced in the final URL with a unique index.
E.g.: if URL ishttp://test.com/value
andindexParam=value
, then the URL
will be:
给定字符串会在最终 URL 替换为唯一索引。
例如:如果 URL 是 http://test.com/value
和 indexParam=value
,之后 URl 会是
- http://test.com/1
- http://test.com/2
- …
- body will also be replaced
body:{userid: id_value}
will bebody:{userid: id_1}
insecure
Allow invalid and self-signed certificates over https.
允许无效和自签名证书通过 https。
secureProtocol
The TLS/SSL method to use. (e.g. TLSv1_method)
使用 TLS/SSL 方法,(例如 TLSv1_method)
Example:
const loadtest = require('loadtest');
const options = {
url: 'https://www.example.com',
maxRequests: 100,
secureProtocol: 'TLSv1_method'
};
loadtest.loadTest(options, function(error) {if (error) {return console.error('Got an error: %s', error);
}
console.log('Tests run successfully');
});
statusCallback
Execution this function after every request operation completes. Provides immediate access to test results while the
test batch is still running. This can be used for more detailed custom logging or developing your own spreadsheet or
statistical analysis of results.
每次请求操作完成后执行此函数。测试批处理仍在运行时提供对测试结果的即时访问。这可以用于更详细的自定义日志记录或开发您自己的电子表格或
统计分析的结果。
The results and error passed to the callback are in the same format as the results passed to the final callback.
传递给回调的结果和错误的格式与传递给最终回调的结果相同。
In addition, the following three properties are added to the
result
object:
需要注意的是,下面三个属性值被添加到 result
对象:
-
requestElapsed
: time in milliseconds it took to complete this individual request. -
requestIndex
: 0-based index of this particular request in the sequence of all requests to be made. -
instanceIndex
: theloadtest(...)
instance index. This is useful if you callloadtest()
more than once. -
requestElapsed
: 完成这个单独的请求所需的时间(毫秒). -
requestIndex
: 基于 0 开始的队列中所有请求的顺序中的索引值。 -
instanceIndex
:loadtest(...)
实例的索引值,如果你多次调用loadtest()
的话这非常有用。
You will need to check if
error
is populated in order to determine which object to check for these properties.
您需要检查是否填充了“error”,以确定要哪些对象来检查这些属性。
(怪怪的,不知道怎么翻)
Example:
const loadtest = require('loadtest');
function statusCallback(error, result, latency) {console.log('Current latency %j, result %j, error %j', latency, result, error);
console.log('----');
console.log('Request elapsed milliseconds:', result.requestElapsed);
console.log('Request index:', result.requestIndex);
console.log('Request loadtest() instance index:', result.instanceIndex);
}
const options = {
url: 'http://localhost:8000',
maxRequests: 1000,
statusCallback: statusCallback
};
loadtest.loadTest(options, function(error) {if (error) {return console.error('Got an error: %s', error);
}
console.log('Tests run successfully');
});
Warning: The format for
statusCallback
has changed in version 2.0.0 onwards.
It used to bestatusCallback(latency, result, error)
,
it has been changed to conform to the usual Node.js standard.
警告:statusCallback 格式在 2.0.0 版本已经改变。
它曾经用 statusCallback(latency, result, error)
,
它已经更改为符合 Nodejs 常用标准
Results
The latency results passed to your callback at the end of the load test contains a full set of data, including: mean latency, number of errors and percentiles.
延迟结果会在负载测试结束时传递给你的回调函数包含完整的数据,包括:平均延迟,错误数量和百分比.
An example follows:
{
totalRequests: 1000,
percentiles: {
'50': 7,
'90': 10,
'95': 11,
'99': 15
},
rps: 2824,
totalTimeSeconds: 0.354108,
meanLatencyMs: 7.72,
maxLatencyMs: 20,
totalErrors: 3,
errors: {
'0': 1,
'500': 2
}
}
The second parameter contains info about the current request:
第二个参数包含当前请求信息
{
host: 'localhost',
path: '/',
method: 'GET',
statusCode: 200,
body: '<html><body>hi</body></html>',
headers: [...]
}
Start Test Server
To start the test server use the exported function
startServer()
with a set of options and an optional callback:
使用导出函数startServer()
开始测试服务器,包含一组选项和一个可选回调;
const testserver = require('testserver');
const server = testserver.startServer({port: 8000});
This function returns an HTTP server which can be
close()
d when it is no longer useful.
函数返回一个 HTTP 服务器当它不再需要的时候能够使用 close()
关闭
The following options are available.
下面可配置项。
port
Optional port to use for the server.
可选端口
Note: the default port is 7357, since port 80 requires special privileges.
注意默认端口为 7357,因为 80 需要特权
delay
Wait the given number of milliseconds to answer each request.
每个请求响应前需要等待多久
error
Return an HTTP error code.
返回 HTTP 错误码
percent
Return an HTTP error code only for the given % of requests.
If no error code was specified, default is 500.
只有给定百分比数量的请求会返回一个 HTTP 错误码。
如果没有指定错误码默认 500
Complete Example
The file
lib/integration.js
shows a complete example, which is also a full integration test:
it starts the server, send 1000 requests, waits for the callback and closes down the server.
lib/integration.js
文件展示完整样例,是一个完整的集成测试;
启动服务器会发送 1000 个请求等待回调函数然后关闭服务器。
Versioning
Version 3.x uses ES2015 (ES6) features,
such asconst
orlet
and arrow functions.
For ES5 support please use versions 2.x.
3.x 版本能使用 ES6 特性,例如 const
或者 let
和箭头函数。
2.x 版本支持 ES5.
Licensed under The MIT License
Copyright (c) 2013-4 Alex Fernández <alexfernandeznpm@gmail.com>
and contributors.
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the ‘Software’), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
特此授予许可, 任何人免费获得这个软件和相关的文档文件的副本(“软件”), 在软件处理无限制, 包括但不限于使用、复制、修改、合并、出版、发行、有偿、和 / 或销售的软件副本权利, 并允许他们软件供应, 应当具备下列条件:
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
上述版权通知和本许可通知应包含在本软件的所有副本或大部分内容中。
THE SOFTWARE IS PROVIDED ‘AS IS’, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
本软件是“按原样”提供的,没有任何明示或暗示的保证,包括但不限于适销性、特定用途的适用性和不侵权的保证。在任何情况下,作者或版权持有人均不应对任何索赔、损害或其他责任承担责任,无论是在合同、侵权或其他行为中,由本软件引起、由本软件引起或与本软件的使用或其他有关交易。