Tuesday, September 6, 2011

On Testing Web Sites using Node.js and Nodeload

Background

At previous employment, over a period of five months an Amazon S3 clone was created; at each step of its implementation every choice was being actively evaluated using numbers generated by a number of tools. Hardware selection, RAID configurations, stored-procedure implementation, REST API approaches - everything was guided by the numbers. One key tool in evaluating choices was node.js plus nodeload. Needing little introduction, node.js with nodeload is taking storm in leading companies as a means to test alternatives without imposing much burden on developers. Developers install node.js, npm, and nodeload on their laptops, and they can set up slaves on any number of computers, to create a load or functionally test a REST API or Web interface.

This document details how to get going and how to use nodeload to test your web application.

Example

For the purposes of illustration the case cited here is a real one: Apache HTTPD with an SNMP module had to be tested for memory leaks, and we needed to distinguish one time leaks from request or connection oriented leaks. A customer noticed increases in memory consumption over a span of a week; what the customer experienced in a week we wanted to reproduced in minutes. We wanted to create a massive amount of load over a short period of time to hopefully distinguish leaks and rank them.

Installation

As root run the following:
mkdir ~/node-latest-install
cd ~/node-latest-install
curl http://nodejs.org/dist/node-latest.tar.gz | tar xz --strip-components=1
./configure
make install
curl http://npmjs.org/install.sh | sh
npm search nodeload
npm install nodeload


Method

Tests are written using javascript, and they are run under node.js+nodeload. The tool chain provides a number of libraries enabling the creation of all sorts of test scenarios and data capture techniques. The system also provides real-time statistics reporting interfaces via HTTP.

Start the Apache server under valgrind.

In your nodeload directory run the test script, here named apsleaks.js. Here is the script's source code:

var http = require('http'),
nl = require('./nodeload');

http.createServer(function (req, res) { res.writeHead(200); res.end(); }).listen(8080);
console.log("Server to load test listening on 8080.");

var loadtest = nl.run({
name: 'Apache Server Memory Leaks',
host: 'myhostname',
port: 37373,
numClients: 20,
timeLimit: 600,
targetRps: 2000000,
stats: ['latency', 'result-codes', {
name: 'http-errors', successCodes: [200],
log: 'http-errors.log' }],
requestGenerator: function(client) {
return client.request('GET', "/", { 'host': 'localhost' });
}
});
loadtest.on('end', function() { process.exit(0); });
To run the nodeload script:
node apsleaks.js


Open up your browser to localhost:8000 to monitor the generated HTTP load. Graphs below show what the output will look like. And nodeload will output to your nodeload directory a results HTML file for permanent record.

Results

Here is resulting output from a nodeload run; you can plainly see the request rate is fairly constant, yet the latency is steadily increasing with ever more server instability.

Alternatively, though a slightly different test that results in 200's instead of 404's, here is resulting output from a nodeload run for a properly running server without resource leaks; notice that latency and instability do not increase over time.

1 comment:

  1. It's not very clear why you run a server at 8080, and port specified as port: 37373

    ReplyDelete