Performance test gadget WRK

       wrk is a relatively advanced HTTP stress testing tool. Wrk can run on one or more core CPUs during load testing. Wrk combines multi-threaded design ideas such as epoll and kqueue, a scalable event notification system. Currently wrk can be installed on Linux systems and Mac systems. With just one command line, you can do many basic http performance tests.

       The open source of wrk, the code is on github. https://github.com/wg/wrk

The first thing to say is: wrk can only run on Unix-like systems. Such as linux, mac, solaris, etc. Compile on these systems.

I have to say here, why many people say that mac is the best development environment. Not because of how high the use of mac is. But you can get the benefits of windows and linux at the same time. Most under linux All development tools can be used on mac. Many of them are precompiled, and some can be used only after compiling.

A good feature of wrk is that it can squeeze a large amount of concurrency with few threads. The reason is that It uses some operating system-specific high-performance io mechanisms, such as select, epoll, kqueue, etc. In fact, it reuses the ae asynchronous event-driven framework of redis. To be precise, the ae event-driven framework is not invented by redis, it comes As for the Tcl interpreter jim, this small and efficient framework is more well-known because it was adopted by redis.

To use wrk, first compile wrk.
You need to have git and a basic c compilation environment installed on your machine. wrk itself is written in c. There is very little code. And it does not use many third-party libraries. What is the problem.

1. git clone https://github.com/wg/wrk.git

 

2. cd wrk

 

3. make

 


That 's ok.
After make is successful, there will be a wrk file in the directory. That's it. You can copy this file to other directories, such as the bin directory. Or just execute it in this directory.

If it appears during the compilation process:

 

1. src/wrk.h:11:25: fatal error: openssl/ssl.h: No such file or directory

 

2. #include <openssl/ssl.h>


It is because the library of openssl is not installed in the system.

sudo apt-get install libssl-dev
or
sudo yum install openssl-devel

 

The installation is complete, configure the environment variable /etc/profile

export PATH=$PATH:/letv/wrk

Effective profile file

source /etc/profile

 

Let's do a simple performance test first:

1.wrk -t2 -c10 -d30s -T30s  --latency http://10.58.100.90/jsondatedemo.txt

Waiting for this test to complete

Running 30s test @ http://10.58.100.90/jsondatedemo.txt
  2 threads and 10 connections
  Thread Stats   Avg      Stdev     Max   +/- Stdev
    Latency   209.38ms  300.23ms   1.99s    90.36%
    Req/Sec    21.81     10.55    60.00     62.24%
  Latency Distribution
     50%  106.14ms
     75%  188.97ms
     90%  491.26ms
     99%    1.56s
  1218 requests in 30.04s, 1.76MB read
  Socket errors: connect 0, read 540, write 0, timeout 30
  Non-2xx or 3xx responses: 540
Requests/sec:     40.55
Transfer/sec:     60.02KB

------------------------------------------------------------------------------------------------

Parameter meaning:

-t thread mode -c simulated concurrency -d duration m minutes s seconds -T set the delay time, the default is 1 second --latency shows the percentage of the user's response time

 

 

 

-------------------------------------------------------------------------------------------------

 -c Generally, the number of threads should not be too much. 2 to 4 times the number of cores is enough. If it is too much, the efficiency will be reduced due to too many thread switching. Because wrk does not use a model of one thread per connection, but improves through asynchronous network io Concurrency. So network communication will not block thread execution. This is why wrk can simulate a large number of network connections with few threads. Now many performance tools do not use this method, but use increasing the number of threads to achieve high Concurrency. So once the concurrency is set high, the pressure on the test machine itself will be very high. The test effect will decrease instead.

-T wrk The default timeout is 1 second. This is a bit short. I usually set it to 30 seconds. This seems reasonable.

 

Thread Stats   Avg      Stdev     Max   +/- Stdev
    Latency   209.38ms  300.23ms   1.99s    90.36%
    Req/Sec    21.81     10.55    60.00     62.24%

Latency: It can be understood as response time, with mean, standard deviation, maximum value, plus or minus one standard deviation ratio.
Req/Sec: The number of completed requests per thread per second, also has mean, standard deviation, The maximum value, plus or minus one standard deviation.

Generally speaking, we mainly focus on the mean value and the maximum value. If the standard deviation is too large, the sample itself has a relatively high degree of dispersion. It is possible that the system performance fluctuates greatly.

 

--latency

  Latency Distribution
     50%  106.14ms
     75%  188.97ms
     90%  491.26ms
     99%    1.56s

 

In 30 seconds, a total of 1218 requests were completed and the amount of data read was 30.04s.
Then there were error statistics. The above statistics can see that there were 540 read errors and 30 timeouts.
Then, the threads completed an average of 40.55 requests per second. . Reads 60.02 megabytes of data per second.

  1218 requests in 30.04s, 1.76MB read
  Socket errors: connect 0, read 540, write 0, timeout 30
  Non-2xx or 3xx responses: 540
Requests/sec:     40.55
Transfer/sec:     60.02KB

wrk supports lua language script. In this script, you can modify the method, header, body, and do a custom analysis of the response. Because it is a lua script, it actually gives you unlimited possibilities. But such a powerful function if If not used carefully, the performance of the test terminal will be degraded, and the test results will also be affected.

Generally, modifying the method, header, and body will not affect the performance of the test terminal, but the operation of request and response should be extra cautious.

Let's see how to use lua scripts through some test scenarios.

POST + header + body.

First create a post.lua file:

1. wrk.method = "POST"

2. wrk.body = "devId=C80E7776704A"

3. wrk.headers["Content-Type"] = "application/x-www-form-urlencoded"


Just these three lines are enough, of course headers can add as much content as you want.
Then execute:

1. wrk -t12 -c100 -d30s -T30s --script=post.lua --latency http://h5.itv.cp21.ott.cibntv.net/api/lottery/draw.json?

---------------------------------------------------------------------------------------------------------------------------------------------

The following are not verified:

Several lua hook functions provided by wrk:

setup function
This function is called when the target IP address has been resolved, and all threads have been generated, but not yet started. Each thread executes this function once.
You can pass thread:get( name), thread:set(name, value) to set thread-level variables.

init function Called before
each request is sent.
Can accept additional arguments on the wrk command line. Specify with --.

delay function
This function returns a value, which is How long to delay the execution of the next request after this request is executed. It can correspond to the scenario of thinking time.

request
function This function can modify the properties of this request before each request. Returns a string. This function should be used with caution. It will affect the performance of the test terminal. The

response function is called after
each request returns. Special processing can be done according to the content of the response, such as stopping the execution of the test when encountering a special response, or outputting to the console, etc.

1. function response(status, headers, body)

2. if status ~= 200 then

3. print(body)

4. wrk.thread:stop()

5. end

6. end



The done function
is called after all requests are executed, and is generally used to customize statistical results.

1. done = function(summary, latency, requests)

2. io.write("------------------------------\n")

3. for _, p in pairs({ 50, 90, 99, 99.999 }) do

4. n = latency:percentile(p)

5. io.write(string.format("%g%%,%d\n", p, n))

6. end

7. end



Here is the complete example given in the wrk source code:

1. local counter = 1

2. local threads = {}

3.

4. function setup(thread)

5. thread:set("id", counter)

6. table.insert(threads, thread)

7. counter = counter + 1

8. end

9.

10. function init(args)

11. requests = 0

12. responses = 0

13.

14. local msg = "thread %d created"

15. print(msg:format(id))

16. end

17.

18. function request()

19. requests = requests + 1

20. return wrk.request()

21. end

22.

23. function response(status, headers, body)

24. responses = responses + 1

25. end

26.

27. function done(summary, latency, requests)

28. for index, thread in ipairs(threads) do

29. local id = thread:get("id")

30. local requests = thread:get("requests")

31. local responses = thread:get("responses")

32. local msg = "thread %d made %d requests and got %d responses"

33. print(msg:format(id, requests, responses))

34. end

35. end



When testing compound scenarios, you can also access multiple urls through lua.
For example, this complex lua script randomly reads the url list in the paths.txt file, and then accesses.:

1. counter = 1

2.

3. math.randomseed(os.time())

4. math.random(); math.random(); math.random()

5.

6. function file_exists(file)

7. local f = io.open(file, "rb")

8. if f then f:close() end

9. return f ~= nil

10. end

11.

12. function shuffle(paths)

13. local j, k

14. local n = #paths

15. for i = 1, n do

16. j, k = math.random(n), math.random(n)

17. paths[j], paths[k] = paths[k], paths[j]

18. end

19. return paths

20. end

21.

22. function non_empty_lines_from(file)

23. if not file_exists(file) then return {} end

24. lines = {}

25. for line in io.lines(file) do

26. if not (line == '') then

27. lines[#lines + 1] = line

28. end

29. end

30. return shuffle(lines)

31. end

32.

33. paths = non_empty_lines_from("paths.txt")

34.

35. if #paths <= 0 then

36. print("multiplepaths: No paths found. You have to create a file paths.txt with one path per line")

37. os.exit()

38. end

39.

40. print("multiplepaths: Found " .. #paths .. " paths")

41.

42. request = function()

43. path = paths[counter]

44. counter = counter + 1

45. if counter > #paths then

46. counter = 1

47. end

48. return wrk.format(nil, path)

49. end



Regarding cookies
, sometimes we need to simulate some scenarios of passing data through cookies. wrk does not have special support, it can be implemented through wrk.headers["Cookie"]="xxxxx".
Here is an example found on the Internet, taking the cookie of Response as a cookie for subsequent requests

1. function getCookie(cookies, name)

2. local start = string.find(cookies, name .. "=")

3.

4. if start == nil then

5. return nil

6. end

7.

8. return string.sub(cookies, start + #name + 1, string.find(cookies, ";", start) - 1)

9. end

10.

11. response = function(status, headers, body)

12. local token = getCookie(headers["Set-Cookie"], "token")

13.

14. if token ~= nil then

15. wrk.headers["Cookie"] = "token=" .. token

16. end

17. end


The positioning of wrk itself is not used to replace professional performance testing tools such as loadrunner. In fact, these functions can fully cope with some performance verification in the usual development process.

Transfer: http://sanwen8.cn/p/1d4kAUJ.html

 

Mount: 224 /letv/wrk

 

 

 

Guess you like

Origin http://10.200.1.11:23101/article/api/json?id=326993143&siteId=291194637