forked from tsenart/vegeta
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Add web server benchmarking script (tsenart#451)
This script will automatically run vegeta against a target with different request rates and graph the latency distribution and success rate at each request rate. Usage: ``` echo GET http://localhost:8080/ | ./ramp-requests.py ``` Dependencies: * vegeta * Python 3 * Gnuplot For more documentation, see https://github.com/tsenart/vegeta/wiki/Load-ramping
- Loading branch information
Showing
3 changed files
with
158 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,17 @@ | ||
# Load ramping | ||
|
||
This script will automatically run vegeta against a target with different request | ||
rates and graph the latency distribution and success rate at each request rate. | ||
|
||
Usage: | ||
|
||
``` | ||
echo GET http://localhost:8080/ | python3 ramp-requests.py | ||
``` | ||
|
||
Dependencies: | ||
|
||
* Python 3 | ||
* Gnuplot | ||
|
||
For more documentation, see https://github.com/tsenart/vegeta/wiki/Load-ramping |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,75 @@ | ||
# Two plots: success rate plot on top, rate/latency distribution below | ||
set multiplot layout 2,1 | ||
|
||
|
||
# | ||
# Shared config | ||
# | ||
|
||
# Scale (x/color) | ||
set autoscale xfix | ||
set logscale xycb 10 | ||
|
||
# Grid | ||
set mxtics 10 | ||
set mytics 10 | ||
set tics scale 0.0000000001 # Tics themselves can't be styled indepedently, so use grid only | ||
set grid xtics ytics mxtics mytics lc rgb '#888888' lw 0.5 lt 1, lc rgb '#888888' lt 1 lw 0.1 | ||
|
||
|
||
# | ||
# Top plot: success rate | ||
# | ||
|
||
# Manual positioning to align both plots | ||
set lmargin at screen 0.10 | ||
set rmargin at screen 0.87 | ||
set bmargin at screen 0.80 | ||
set tmargin at screen 0.95 | ||
|
||
# Scale (y only) | ||
set yrange [1.0:100.0] | ||
|
||
# Axes | ||
unset xlabel | ||
set xtics format "" | ||
set ylabel "Success" | ||
set ytics format "%.2f%%" | ||
|
||
# Plot (incl. fraction to percentage conversion) | ||
plot "results_success.txt" using 1:($2 * 100.0):(0.0) with line lw 3 lc rgb "red" title "" | ||
|
||
|
||
# | ||
# Bottom plot: rate vs latency | ||
# | ||
|
||
# Manual positioning to align both plots | ||
set lmargin at screen 0.10 | ||
set rmargin at screen 0.87 | ||
set tmargin at screen 0.75 | ||
set bmargin at screen 0.15 | ||
|
||
# Scale (y only) | ||
unset yrange | ||
set autoscale yfix | ||
|
||
# Axes | ||
set xlabel "Requests (per sec)" | ||
set xtics format "%.f" | ||
set ylabel "Latency" offset -1.5,0,0 | ||
set ytics ( \ | ||
"1ns" 1.0e0, "10ns" 1.0e1, "100ns" 1.0e2, \ | ||
"1us" 1.0e3, "10us" 1.0e4, "100us" 1.0e5, \ | ||
"1ms" 1.0e6, "10ms" 1.0e7, "100ms" 1.0e8, \ | ||
"1s" 1.0e9, "10s" 1.0e10, "100s" 1.0e11 ) | ||
|
||
# Color box | ||
set cblabel "" | ||
set cbrange[0.001:100.0] | ||
set format cb "%.9g%%" | ||
|
||
# Plot (incl. fraction to percentage conversion) | ||
set datafile separator " " | ||
set pm3d map corners2color c1 | ||
splot "results_latency.txt" u 1:2:($3 * 100.0) with pm3d title "" |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,66 @@ | ||
#!/usr/bin/env python3 | ||
|
||
import json | ||
import os | ||
import subprocess | ||
import sys | ||
import time | ||
|
||
|
||
if '-h' in sys.argv or '--help' in sys.argv: | ||
print('usage:', file=sys.stderr) | ||
print('echo GET http://localhost:8080/ | %s' % sys.argv[0], file=sys.stderr) | ||
sys.exit(1) | ||
|
||
target = sys.stdin.read().strip() | ||
|
||
|
||
# Log-spaced rates (each ca. +25% (+1dB) of the previous, covering 1/sec to 100k/sec) | ||
rates = [10.0 ** (i / 10.0) for i in range(50)] | ||
|
||
# Log-spaced buckets (each ca. +25% (+1dB) of the previous, covering <1us to >10s) | ||
buckets = [0] + [1e3 * 10.0 ** (i / 10.0) for i in range(71)] | ||
|
||
|
||
# Run vegeta attack | ||
for rate in rates: | ||
filename='results_%i.bin' % (1000*rate) | ||
if not os.path.exists(filename): | ||
cmd = 'vegeta attack -duration 5s -rate %i/1000s -output %s' % (1000*rate, filename) | ||
print(cmd, file=sys.stderr) | ||
subprocess.run(cmd, shell=True, input=target, encoding='utf-8') | ||
time.sleep(5) | ||
|
||
|
||
# Run vegeta report, and extract data for gnuplot | ||
with open('results_latency.txt', 'w') as out_latency, \ | ||
open('results_success.txt', 'w') as out_success: | ||
|
||
for rate in rates: | ||
cmd = 'vegeta report -type=json -buckets \'%s\' results_%i.bin' \ | ||
% ("[%s]" % ",".join("%ins" % bucket for bucket in buckets), 1000*rate) | ||
print(cmd, file=sys.stderr) | ||
result = json.loads(subprocess.check_output(cmd, shell=True)) | ||
|
||
# (Request rate, Response latency) -> (Fraction of responses) | ||
for latency, count in result['buckets'].items(): | ||
latency_nsec = float(latency) | ||
fraction = count / sum(result['buckets'].values()) * result['success'] | ||
print(rate, latency_nsec, fraction, file=out_latency) | ||
print(file=out_latency) | ||
|
||
# (Request rate) -> (Success rate) | ||
print(rate, result['success'], file=out_success) | ||
|
||
print('# wrote results_latency.txt and results_success.txt', file=sys.stderr) | ||
|
||
|
||
# Visualize with gnuplot (PNG) | ||
cmd = 'gnuplot -e "set term png size 1280, 800" ramp-requests.plt > result.png' | ||
print(cmd, file=sys.stderr) | ||
subprocess.run(cmd, shell=True) | ||
|
||
# Visualize with gnuplot (default, likely a UI) | ||
cmd = 'gnuplot -persist ramp-requests.plt' | ||
print(cmd, file=sys.stderr) | ||
subprocess.run(cmd, shell=True) |