Quick Start for the http Pressure Tool wrk

Posted by AZDoc on Wed, 19 Feb 2020 18:33:23 +0100


Quick Start for the http Pressure Tool wrk

Thank you, teacher cap1537

I've used a lot of manometry tools, but I haven't found the one I like.It feels good to try wrk recently. Write down this guide for yourself to remember, and if it helps you, it's also good.


Wrk supports most UNIX-like systems and does not support windows.Operating systems are required to support LuaJIT and OpenSSL, but don't worry, most Unix-like systems support them.Installing wrk is simple, simply download the wrk source from github and execute the make command in the project path.

  • mac
brew install wrk
  • linux
git clone https://github.com/wg/wrk


After make, the executable wrk is generated in the project path and can then be used for HTTP testing.You can copy this executable to a path that is already in the path, such as/usr/local/bin, so you can use wrk directly in any path. By default, wrk uses its own LuaJIT and OpenSSL, and if you want to use the version installed on your system, you can specify their paths using the options WITH_LUAJIT and WITH_OPENSSL.For example:


Basic Use

You can see help when you hit wrk on the command line

Usage: wrk <options> <url>
    -c, --connections <N>  Connections to keep open
    -d, --duration    <T>  Duration of test
    -t, --threads     <N>  Number of threads to use

    -s, --script      <S>  Load Lua script file
    -H, --header      <H>  Add header to request
        --latency          Print latency statistics
        --timeout     <T>  Socket/request timeout
    -v, --version          Print version details

  Numeric arguments may include a SI unit (1k, 1M, 1G)
  Time arguments may include a time unit (2s, 2m, 2h)

Simple translation into Chinese: Usage: wrk <options> <URL of HTTP service under test>

    -c, --connections <N>  Established and maintained with the server TCP Number of connections
    -d, --duration    <T>  Pressure Time
    -t, --threads     <N>  How many threads to use for pressure measurement

    -s, --script      <S>  Appoint Lua Script Path
    -H, --header      <H>  For each HTTP Request Add HTTP head
        --latency          Print delay statistics after the manometry is complete
        --timeout     <T>  timeout
    -v, --version          Print in Use wrk Detailed version information for

  <N>Represents numeric parameters, supports international units (1k, 1M, 1G)
  <T>Represents a time parameter, supporting time units (2s, 2m, 2h)

Look at the version

wrk -v


wrk 4.0.2 [epoll] Copyright (C) 2012 Will Glozer

You see a version 4.0.2 wrk with epoll.This means that we can create a large number of connections to the service under test with a small number of threads for pressure measurement. Do a simple manometry and analyze the results

wrk -t8 -c200 -d30s --latency  "http://www.bing.com"


Running 30s test @ http://www.bing.com
  8 threads and 200 connections
  Thread Stats   Avg      Stdev     Max   +/- Stdev
    Latency    46.67ms  215.38ms   1.67s    95.59%
    Req/Sec     7.91k     1.15k   10.26k    70.77%
  Latency Distribution
     50%    2.93ms
     75%    3.78ms
     90%    4.73ms
     99%    1.35s
  1790465 requests in 30.01s, 684.08MB read
Requests/sec:  59658.29
Transfer/sec:     22.79MB

The above uses eight threads with 200 connections to measure the bing home page for 30 seconds and requires response latency information to be output in the results.The following is a brief comment on the results of the manometry:

Running 30s test @ http://www.bing.com (Pressure time 30s)
  8 threads and 200 connections (A total of 8 test threads, 200 connections)
  Thread Stats   Avg      Stdev     Max   +/- Stdev
              (Average (Standard Deviation) (Maximum) (Percentage of one Standard Deviation plus or minus)
    Latency    46.67ms  215.38ms   1.67s    95.59%
    Req/Sec     7.91k     1.15k   10.26k    70.77%
    (Number of requests in process)
  Latency Distribution (Delay Distribution)
     50%    2.93ms
     75%    3.78ms
     90%    4.73ms
     99%    1.35s (99 Delay in quantification)
  1790465 requests in 30.01s, 684.08MB read (30.01 A total of 1790465 requests were processed and 684 read in seconds.08MB Data)
Requests/sec:  59658.29 (Average processing complete 59658 per second.29 Requests)
Transfer/sec:     22.79MB (Average data read per second 22.79MB)

You can see that wrk is easy to use and the results are clear.And because of the use of non-blocking IO, a large number of connections can be created on the ordinary test machine to achieve good pressure measurement results.

Personalize wrk manometry using Lua scripts

The above two sections install and simply use wrk, but this simple measurement may not meet our needs.For example, we may need to use POST METHOD to interact with the server; we may need to use different parameters for each request to better simulate the actual usage scenario of the service, and so on.Wrk supports users to specify Lua scripts using script to customize the maneuver process to meet personalized needs.

Describes wrk's support for Lua scripting

wrk supports personalization of manometry in three phases: start, run and end.Each test thread has a separate Lua runtime environment. Startup phase

function setup(thread)

Implementing the setup method in a script file invokes wrk when the test thread has been initialized but not started.Wrk calls the setup method once for each test thread and passes in an object threads representing the test thread as an argument.The threadobject can be manipulated in the setup method to get information, store information, or even close the thread.

thread.addr             - get or set the thread's server address
thread:get(name)        - get the value of a global in the thread's env
thread:set(name, value) - set the value of a global in the thread's env
thread:stop()           - stop the thread
//Running phase
function init(args)
function delay()
function request()
function response(status, headers, body)

init is called by the test thread only once when it enters the run phase.Supports getting command line parameters from the command that starts wrk; Delay is called before each request is sent, and if delay is required, delay corresponds to time; Requests are used to generate requests; each request calls the method, so be careful not to do time-consuming operations in the method; reponse is called each time a response is received; to improve performance, if this method is not defined, wrk will not resolve headers and bodies; End Stage

function done(summary, latency, requests)

This method is called only once throughout the test process, and the test results can be obtained from the object given the parameters, and a customized test report can be generated. Accessible variables and methods in custom scripts

Variables: wrk
 wrk = {
    scheme  = "http",
    host    = "localhost",
    port    = nil,
    method  = "GET",
    path    = "/",
    headers = {},
    body    = nil,
    thread  = <userdata>,

A table type variable wrk is a global variable, and modifying the table affects all requests.

Method: wrk.fomat wrk.lookup wrk.connect
  function wrk.format(method, path, headers, body)

    wrk.format returns a HTTP request string containing the passed parameters
    merged with values from the wrk table.
    //Generates an HTTP rquest string based on the parameters and the global variable wrk.

  function wrk.lookup(host, service)

    wrk.lookup returns a table containing all known addresses for the host
    and service pair. This corresponds to the POSIX getaddrinfo() function.
    //Given host and service (port/well known service name), return all available server address information.

  function wrk.connect(addr)

    wrk.connect returns true if the address can be connected to, otherwise
    it returns false. The address must be one returned from wrk.lookup().
    //Test if the connection can be successfully created with the given server address information


wrk.method = "POST"
wrk.body = "foo=bar&baz=quux"
wrk.headers\["Content\-Type"\] = "application/x\-www\-form\-urlencoded"

Modify the global variable wrk so that all requests use the POST method and specify the body and Content-Type headers. Change one parameter for each request

request = function()
uid = math.random(1, 10000000)
path = "/test?uid=" ... uid
return wrk.format(nil, path)

By randomly generating UIDs between 1 and 10000000 in the request method, the uid parameters in the request are random. Delay 10 ms before each request

function delay()
return 10

Each thread needs to authenticate first, then acquire token for pressure testing

token = nil
path = "/authenticate"

request = function()
return wrk.format("GET", path)

response = function(status, headers, body)
if not token and status == 200 then
token = headers\["X\-Token"\]
path = "/resource"
wrk.headers\["X\-Token"\] = token

In the absence of token, first access/authenticate authentication.After successful authentication, read token and replace path with/resource. Pressure services supporting HTTP pipeline

init = function(args)
local r = {}
r\[1\] = wrk.format(nil, "/?foo")
r\[2\] = wrk.format(nil, "/?bar")
r\[3\] = wrk.format(nil, "/?baz")

req = table.concat®

request = function()
return req

By splicing three HTTP request requests together in the init method, three requests are sent at a time to use the HTTP pipeline.

Topics: Programming Unix OpenSSL github Windows