Getting ready for a big event on your website? Re-architecting for better performance or scalability? Releasing a hot new feature? Load testing can help you plan and provision accordingly. In this talk, I'll briefly discuss load testing strategies, then dive into how to DIY with Python using Corey Goldberg's open source library multi-mechanize as well as how to gather performance data from your tests. Real-life examples against a deployment of a popular open-source Python web app (reddit!).
3. MENU
• What is load testing?
• How does it work?
• One good way to do it
• (with Python, no less!)
• A few examples
• Survey: making sense of it all
3
4. WHAT IS LOAD TESTING
• AKA stress testing
• Putting demand on a system (web app)
and measuring its response (latency,
availability)
http://www.flickr.com/photos/60258236@N02/5515327431/
4
5. Q: WILL IT PERFORM
Do my code + infrastructure provide the
desired level of performance in terms of
latency and throughput for real user
workloads?
And if not, how can I get there?
5
10. A PAGEVIEW IS BORN
yslow?
DNS, connection
Fulfill HTTP Request (“Time to first byte”)
Download + render page contents
(+js)
10
11. HOW TO TEST IT
most common • “F*ck it, we’ll do it live!”
• Synthetic HTTP requests
(“Virtual Users / VUs”)
least common
• Synthetic clicks in real
browsers (“RBUs”)
11
12. VU vs RBU
VU RBU
• Simulate individual • Operate a browser
protocol-level requests
• Low overhead • Higher overhead
• Scripts must parallel user • Scripts must parallel user
behavior behavior
• Tough to get AJAX-heavy • Accurate simulation of
sites exactly right, maintain AJAX
12
13. MULTI-MECHANIZE
• FOSS (LGPL v3), based on mechanize
• Load generation framework for VUs
• Written in Python, scripted in Python
• Heavyweight for bandwidth-bound
tests, but stocked with py-goodness
13
14. MULTI-MECHANIZE
• Basic idea:
• Write a few scripts that simulate
user actions or paths
• Specify how you want to run them:
x VUs in parallel on script A, y on
script B, ramping up, etc.
• Run and watch
14
15. A SIMPLE M-M SCRIPT
get_index.py
import
requests
class
Transaction(object):
def
run(self):
r
=
requests.get(‘http://website.com/’)
r.raw.read()
15
16. A SIMPLE PROJECT
• A multi-mechanize “project” is a set of
test scripts and a config that specifies
how to run them:
dan@host:~/mm/my_project$
ls
-‐1
.
..
config.cfg
#
config
file
test_scripts/
#
your
tests
are
here
results/
#
result
files
go
here
16
18. A FEW M-M FEATURES
features.py
import
requests
import
time
class
Transaction(object):
def
run(self):
r
=
requests.get(‘http://website.com/a’)
r.raw.read()
assert
(r.status_code
==
200),
‘not
200’
assert
(‘Error’
not
in
r.text)
t1
=
time.time()
r
=
requests.get(‘http://website.com/b’)
r.raw.read()
latency
=
time.time()
-‐
t1
self.custom_timers[‘b’]
=
latency
18
24. GETTING INSIGHT
• Second, why is the machine working
hard?
• What is my app doing?
• What are my databases doing?
• How are my caches performing?
24
25. REDDIT: A PYLONS APP
nginx
memcached uwsgi
pylons
postgresql cassandra
queued jobs
25
26. REDDIT: A PYLONS APP
request start
nginx
memcached uwsgi
pylons
postgresql cassandra
queued jobs request end
26
27. REDDIT: A PYLONS APP
request start
nginx
memcached uwsgi
pylons
postgresql cassandra
queued jobs request end
27
28. INSIDE THE APP
PROFILING VS INSTRUMENTATION
• Fine-grained analysis of • Gather curated set of
Python code information
• Easy to set up • Requires monkey-patching
(or code edits)
• No visibility into DB, • Can connect DB, cache
cache, etc. performance to app
• Distorts app performance • Little (tunable) overhead
• profile, cProfile • django-debug-toolbar,
statsd, Tracelytics, New Relic
28
37. AND: TRACELYTICS FREE TRIAL
We’ve got a 14-day trial; with only
minutes to install, you’ll have plenty of
time for load testing. No credit card
required!
http://tracelytics.com
37