On 07/02/2012 08:58, André Warnier wrote:
ab isn't usually that much use as it does strain the databases in the same way - especially as it only takes 1 URL - any "production" scaling e.g. caching etc will make it even worse. I have a simple one I wrote based on curl which can take a list of URLs which is generally a lot better. Without being careful it is still difficult to cope with large sites acting like users (you will need to extend the code to do cookie jars!)...Tobias Wagener wrote:Hello,I'm currently developing a huge application with mod_perl, unixODBC and MaxDB/SAPDB.On my developing system everything is fine. But on the productive systemwith > 50 users, I have database connection errors and request aborts andso on.Now I want to ask if someone knows a tool or perl modules, where I can simulate 50 users. I have a list with some common request including the query parameter in order of appearence. But I don't know, how to send them to my developing system to create the same load as it will be on the productive system.Can someone help me with this issue?As a simple tool, have a look at the "ab" program that comes with Apache.
Things we have come across in large production systems are. * Apache::DBI sometimes cause issues with too many database connections - we tend to turn it off and use DBIx::Connector as mentioned (and carefully selected caching) here to cope with persistence of connections; * You may be serving too many requests on the server to the users (other than the main page request).... look at caching/minimising/merging page design elements - background images, javascript, CSS; * OR - serve them from a second apache (use it either as a proxy or have a proxy in front of the two apaches) * Don't over AJAX pages - lots of "parallel" AJAX requests can effectively DOS your service;Another trick is to add extra diagnostics to your apache logs with a couple of mod_perl handlers:
*Apache configuration file:* PerlLoadModule Pagesmith::Apache::Timer PerlChildInitHandler Pagesmith::Apache::Timer::child_init_handler PerlChildExitHandler Pagesmith::Apache::Timer::child_exit_handlerPerlPostReadRequestHandler Pagesmith::Apache::Timer::post_read_request_handler
PerlLogHandler Pagesmith::Apache::Timer::log_handlerLogFormat "%V [*%P/%{CHILD_COUNT}e %{SCRIPT_TIME}e* %{outstream}n/%{instream}n=%{ratio}n] %h/%{X-Forwarded-For}i %l/%{SESSION_ID}e %u/%{user_name}e %t \"%r\" %>s %b \"%{Referer}i\" \"%{User-Agent}i\ " \"%{Cookie}i\" \"%{X-Requested-With}i\" *%{SCRIPT_START}e/%{SCRIPT_END}e*" diagnostic
The following module sets up the four environment variables: *CHILD_COUNT, SCRIPT_START, SCRIPT_END, SCRIPT_TIME* so you can see which requests are slow and you can also see if you have any "clustering" of requests...Setting the "Readonly my $LEVEL" to either normal or noisy will give you more diagnostics in the error log as well....
*Module:* package Pagesmith::Apache::Timer; ## Component ## Author : js5 ## Maintainer : js5 ## Created : 2009-08-12 ## Last commit by : $Author: js5 $ ## Last modified : $Date: 2011-10-26 12:44:20 +0100 (Wed, 26 Oct 2011) $ ## Revision : $Revision: 1489 $## Repository URL : $HeadURL: svn+ssh://web-svn.internal.sanger.ac.uk/repos/svn/shared-content/trunk/lib/Pagesmith/Apache/Timer.pm $
use strict;
use warnings;
use utf8;
use version qw(qv); our $VERSION = qv('0.1.0');
use Readonly qw(Readonly);
Readonly my $VERY_LARGE_TIME => 1_000_000;
Readonly my $CENT => 100;
Readonly my $LEVEL => 'normal'; # (quiet,normal,noisy)
use Apache2::Const qw(OK DECLINED);
use English qw(-no_match_vars $PID);
use Time::HiRes qw(time);
my $child_started;
my $request_started;
my $requests;
my $total_time;
my $min_time;
my $max_time;
my $total_time_squared;
sub post_config_handler {
return DECLINED if $LEVEL eq 'quiet';
printf {*STDERR} "TI: Start apache %9d\n", $PID;
return DECLINED;
}
sub child_init_handler {
return DECLINED if $LEVEL eq 'quiet';
$child_started = time;
$requests = 0;
$total_time = 0;
$min_time = $VERY_LARGE_TIME;
$max_time = 0;
$total_time_squared = 0;
printf {*STDERR} "TI: Start child %9d\n", $PID;
return DECLINED;
}
sub post_read_request_handler {
my $r = shift;
return DECLINED if $LEVEL eq 'quiet';
$request_started = time;
$requests++;
return DECLINED unless $LEVEL eq 'noisy';
printf {*STDERR} "TI: Start request %9d - %4d %s\n",
$PID,
$requests,
$r->uri;
return DECLINED;
}
sub log_handler {
my $r = shift;
return DECLINED if $LEVEL eq 'quiet';
my $request_ended = time;
my $t = $request_ended - $request_started;
$total_time += $t;
$min_time = $t if $t < $min_time;
$max_time = $t if $t > $max_time;
$total_time_squared += $t * $t;
$r->subprocess_env->{'CHILD_COUNT'} = $requests;
$r->subprocess_env->{'SCRIPT_START'} = sprintf '%0.6f', $request_started;
$r->subprocess_env->{'SCRIPT_END'} = sprintf '%0.6f', $request_ended;
$r->subprocess_env->{'SCRIPT_TIME'} = sprintf '%0.6f', $t;
return DECLINED unless $LEVEL eq 'noisy';
printf {*STDERR} "TI: End request %9d - %4d %10.6f %s\n", $PID,
$requests, $t, $r->uri;
return DECLINED;
}
sub child_exit_handler {
return DECLINED if $LEVEL eq 'quiet';
my $time_alive = time - $child_started;
printf {*STDERR} "TI: End child %9d - %4d %10.6f %10.6f %7.3f%%
%10.6f [%10.6f,%10.6f]\n",
$PID,
$requests,
$total_time,
$time_alive,
$time_alive ? $CENT * $total_time / $time_alive : 0,
$requests ? $total_time / $requests : 0,
$min_time,
$max_time;
return DECLINED;
}
1;
--
The Wellcome Trust Sanger Institute is operated by Genome Research
Limited, a charity registered in England with number 1021457 and a
company registered in England with number 2742969, whose registered
office is 215 Euston Road, London, NW1 2BE.
curl-get-pages.tgz
Description: application/compressed
