Skip to content

Commit

Permalink
Add web server benchmarking script (tsenart#451)
Browse files Browse the repository at this point in the history
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
fxkr authored and tsenart committed Jan 12, 2020
1 parent 37da2b6 commit 85244b4
Show file tree
Hide file tree
Showing 3 changed files with 158 additions and 0 deletions.
17 changes: 17 additions & 0 deletions scripts/load-ramping/README.md
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
75 changes: 75 additions & 0 deletions scripts/load-ramping/ramp-requests.plt
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 ""
66 changes: 66 additions & 0 deletions scripts/load-ramping/ramp-requests.py
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)

0 comments on commit 85244b4

Please sign in to comment.