Recently I wanted to simulate “slow” requests against a web server in order to investigate how high latency requests impacted the system overall. After some initial experimentation with writing my own code (in python), I started looking around for other solutions. I wanted to be able to use Multi-Mechanize, one of my favorite tools for http testing, without heavy modification. Eventually I stumbled onto netem. From the FAQ:
Netem allows testing of protocols and applications on a local network with simulated wide area networks. This was originally done to test congestion algorithms in TCP/IP, but is equally applicable to web applications and file servers.It’s dirt simple to use, and allows you to stick with whatever http traffic generating tools you like. Here’s a few simple examples along with their impact.
Multi-Mechanize Configuration
[global]
run_time: 30
rampup: 0
results_ts_interval: 5
progress_bar: on
console_logging: off
xml_report: off
[user_group-1]
threads: 3
script: example_httplib.py
Multi-Mechanize Test Script
import httplib
import time
class Transaction(object):
def __init__(self):
self.custom_timers = {}
def run(self):
start_timer = time.time()
conn = httplib.HTTPConnection('www.google.com')
conn.request('GET', '/')
resp = conn.getresponse()
content = resp.read()
latency = time.time() - start_timer</p>
self.custom_timers['Google'] = latency
assert (resp.status == 200), 'Bad HTTP Response'
if __name__ == '__main__':
trans = Transaction()
trans.run()
print trans.custom_timers
First, the control run (no artificial latency introduced):
Next, let’s add 100ms latency:
[root@aenea multi-mechanize_1.011]# tc qdisc change dev wlan0 root netem delay 100ms
Now let’s do 100ms latency, with a 20ms variation with a normal distribution:
[root@aenea multi-mechanize_1.0.11]# tc qdisc change dev wlan0 root netem delay 100ms 20ms distribution normal
This is really just scratching the surface with netem. You can use it for:
- Delay
- Variable Delay
- Delay Distribution
- Packet Loss
- Packet Reordering
- Rate Control