Crates.io | rsb |
lib.rs | rsb |
version | 0.2.2 |
source | src |
created_at | 2023-03-18 15:33:12.347254 |
updated_at | 2024-01-23 16:09:43.662939 |
description | a http server benchmark tool, written in rust. |
homepage | https://github.com/gamelife1314/rsb |
repository | https://github.com/gamelife1314/rsb |
max_upload_size | |
id | 813800 |
size | 746,070 |
rsb
is a http server benchmark tool written in rust. The development of this tool is mainly inspired
by the bombardier
project, and I would like to thank the author for his
contribution. On the other hand, this tool was developed primarily to learn and understand Rust.
If you are a Rust developer,and you have already installed Rust-related toolchains locally, you can install them through Cargo.
cargo install rsb
Or you can go Release Page to download the compiled version for the corresponding platform. If docker is installed, you can directly use the compiled docker image
// image from github container registry
docker run --rm ghcr.io/gamelife1314/rsb -n 50 -l -c 10 https://httpbin.org
// image from docker hub
docker run --rm gamelife1314/rsb -n 50 -l -c 10 https://httpbin.org
If you want to use the automatic completion function of the shell, you can output the completion script corresponding
to the shell through a command similar to the following. rsb
supports bash
, elvish
, fish
, powershell
, and zsh
.
For example:
eval "$(rsb --completions zsh)"
First, let's take a look at the overall picture of this tool:
The tool has two modes when running, which must be specified when using it. One is based on the total amount, that is,
you need to declare how many requests you need to send in total, which can be specified by the -n
parameter. The other
is based on the running time, which means how long you need to test, which can be specified by the -d
parameter, and
the unit is seconds.
First, let's look at the example of specifying the total amount:
Let's look at another example of specifying the test duration:
During use, we usually encounter too many specified numbers, or the specified test time is too long. When you want to
cancel in the middle, you can cancel it directly through ctrl-c
. After the tool receives the signal, it will complete
the current request. Exit directly and output the current statistics.
Item | Description |
---|---|
Reqs/Sec |
Count the requests sent and received responses per second, and then calculate the average, maximum, and standard deviation. |
Latency |
Record the time taken for each request from sending to receiving the response, and then calculate the average, maximum and standard deviation |
Latency Distribution |
Sort the time consumption of each request, and then take out the data under each percentage to calculate its average. |
HTTP codes |
Quantity statistics of various response codes |
Throughput |
Throughput is obtained by dividing the number of concurrency and the average request time, and the unit is: reqs/s |
Custom request headers can be specified via the -H
parameter, example: -H=k:v,k1:v1
. It should be noted that if
Content-Type
is set, but --json-file
, --json-body
, --text-file
, --text-body
, --mp
, --mp-file
, --form
are also set , then it will be overwritten.
The tool core uses request
to send Http requests, so it currently inherits
its support for proxies. The proxy for HTTP requests can be set through the environment variable http_proxy
, and the
proxy for HTTPS requests can be set through the environment variable https_proxy
. The use of socks
proxy is also
supported. Here
are more declarations about proxies.
example:
export http_proxy=http://127.0.0.1:1087;export https_proxy=http://127.0.0.1:1087;export ALL_PROXY=socks5://127.0.0.1:1080
If you want to set the request body as a text type, you can specify a file as input through --text-file
, or specify a
string through --text-body
. Note that these two parameters can only be selected from one of the two, and cannot
coexist with other request body setting parameters. when requesting, the content type will be specified as: text/plain
.
example:
rsb -n 100 --text-body "anything" http://127.0.0.1:8000/post-text
// or
rsb -n 1 -m POST --text-body "chatgpt4.0 is coming and very strong" http://127.0.0.1:54326/post-text
If the data type you want to send is JSON, you can specify it with the --json-body
parameter, or read it from a
file with --json-file
. When requesting, the request type will be specified as: application/json
.
example:
rsb -n 1 -m POST --json-body '{"version":"v0.1.0","name":"rsb"}' http://127.0.0.1:54326/post-json
// or
rsb -n 1 -m POST --json-file json.txt http://127.0.0.1:54326/post-json
// or build json body from external command, this will call rsbg program to generate request body
cargo run -- -c 50 -t 5s -n 5000 -l --json-command "rsbg hello world xxx 1" -m POST http://127.0.0.1:5302/hello
If you want to send a request of type application/x-www-form-urlencoded
, you need to pass the --form
parameter.
This parameter can be specified multiple times, and multiple key-value pairs can be declared each time.
example:
rsb -n 1 -m POST --form=k:v,k1:v1 --form=k2:v2 http://127.0.0.1:54326/post-form
If you want to send a request of multipart/form-data
type, or want to upload a file, you can specify parameters
through --mp
and specify the file to be uploaded through --mp-file
.
example:
rsb -n 1 -m POST --mp-file=f1:LICENSE,rsb:target/debug/rsb.exe --mp=k1:v1 http://127.0.0.1:54326/upload-file
If the server needs to verify the client's certificate, you can pass --cert
and --key
to specify the client's
certificate and key respectively.
example:
rsb -n 500 -l --cert client.pem --key client-key.pem https://127.0.0.1:9443/hello
You can refer to the following Go code to generate and start an https server for testing:
...
func main() {
caCert, _ := ioutil.ReadFile("rootCa.pem")
caCertPool := x509.NewCertPool()
caCertPool.AppendCertsFromPEM(caCert)
tlsConfig := &tls.Config{
ClientCAs: caCertPool,
ClientAuth: tls.RequireAndVerifyClientCert,
}
tlsConfig.BuildNameToCertificate()
server := &http.Server{
Addr: ":9443",
TLSConfig: tlsConfig,
}
http.HandleFunc("/hello", hello)
http.HandleFunc("/headers", headers)
if err := server.ListenAndServeTLS("server.pem", "server-key.pem"); err != nil {
fmt.Println(err)
}
}