Re: LWP
Bowen Dwelle (bowen@hotwired.com)
Tue, 02 Sep 1997 19:23:13 -0700
I have some simple code that we use for this. It forks X child processes
that each hit a specified URL; you can use it to time throughput and
latency, at least until you run up against the performace of the test
client machine.
-------------------------------------snip------------------------------------
#!/usr/local/bin/perl
$usage = <<END;
usage: $0
--children|c <int>(1) number of concurrent forked
processes to spawn
--queries|q <int>(20) number of queries to run
END
use Benchmark;
use Carp;
use Data::Dumper;
use Getopt::Long;
use FileHandle;
use LWP::UserAgent;
use URI::URL;
$logfile = './load.log';
$LOG = FileHandle->new( ">> $logfile" ) || die "couldn't open logfile:
$logfile\n";
$| = 1;
# arguments
%opt = ();
$result = &GetOptions (
\%opt,
"config",
"debug",
"help",
"children|c:i",
"queries|q:i",
"host|h:s",
) ;
if ( ! $result || $opt{'help'}) {
print $usage;
croak "Invalid command line option(s)";
}
$children = $opt{children} || 1;
$queries = $opt{queries} || 20;
$engine = $opt{host} || '';
$use_wordlist = 0;
$root_url = "http://$host";
$queriestotal = $children * $queries;
print <<END;
This is the load test client.
child processes $children
queries $queries
total queries $queriestotal
root_url $root_url
END
croak "--config was used\n" if $opt{config};
#######################################################
#######################################################
#######################################################
# create a bunch of children listening to our semaphore
$time0 = Benchmark->new();
my $i;
for $i (1..$children)
{
FORK: {
my $pid;
unless ($pid = fork)
{
if (defined $pid)
{
my $countthing = 0;
my $ua = new LWP::UserAgent;
print "IN CHILD $i -- $$\n";
print $PID "$pid\n"; # record process ID
srand( time() ^ ($$ + ($$ << 15)));
for (1..$queries)
{
$countthing++;
my $url = new URI::URL $root_url;
my $url_string = $url->as_string;
print "CHILD $i -- query $countthing: $query -- url: $url_string\n";
my $request = new HTTP::Request('GET',$url);
my $response = $ua->request($request);
my $results = $response->title;
## my $content = $response->content;
## print "CONTENT:\n$content\n";
print "CHILD $i -- results: $results\n";
}
print "CHILD $i EXITING\n";
exit 1;
}
elsif ($! =~ /No more process/)
{
# if we wait we can fork?
sleep 5; redo FORK;
}
else
{
# irrecoverable error
croak "Can't fork\n";
}
}
}
}
#######################################################
for $i (1..$children) { wait; }
$| = 1;
$time1 = Benchmark->new();
print "STOPPING TIMER\n";
my $T = timestr(timediff($time1, $time0));
$PID->close;
$c = $children;
$q = $queries;
$Q = $queriestotal;
eval { $QT = sprintf "%.2f", ( $Q / $T ); };
eval { $TQ = sprintf "%.2f", ( $T / $Q ); };
eval { $Tq = sprintf "%.2f", ( $T / $q ); };
# format $T for human consumption
$hT = 0.001;
$hT = int($1) if ($T =~ /(.*)secs/);
$hT = 1 if ($hT < 1);
print <<END;
RESULTS
Children (c) $c
Queries/child (q) $q
Total Queries (Q) $Q
Total time (T) $hT
throughput (Q/T) $QT
time per query (T/Q) $TQ
user time per query (T/q) $Tq
END
$D = scalar(localtime);
$logstuff = join ( ',', $c, $Tq, $q, $Q, $hT, $QT, $TQ, $Tq, $D, $host );
print $LOG $logstuff, "\n";
exit;
-------------------------------------snip------------------------------------
At 04:30 PM 9/2/97 -0400, Ledbetter, Bruce wrote:
>
>
>
>I need an application to test the performance of a web server. We are
>particularly
>interested in hitting the server with many simultaneous request. When the
>site in
>question goes live, we expect it to be hit very hard, and we want to be sure
>it can handle the load. We would like to try to simulate this before we
>launch the site.
>
>I've been reading the "Web Client Programming" book, by O'Reilly and it
>seems that I might be able to do what I want in Perl using LWP. Would
>anyone
>care to comment on my approach? Are there other tools out there I should
>know about that do this already?
>
>Thanks,
>Bruce Ledbetter
>Ammirati Puris Lintas
>
>
>
Bowen Dwelle -- 415 276.8607