Re: Tool to create multiple requests

James Smith <[email protected]>
Newsgroups gmane.comp.apache.mod-perl
Message-ID <[email protected]>
On 07/02/2012 08:58, André Warnier wrote:
> 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 system
>> with > 50 users, I have database connection errors and request aborts 
>> and
>> so 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.
>
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!)...

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_handler
PerlPostReadRequestHandler  
Pagesmith::Apache::Timer::post_read_request_handler
PerlLogHandler              Pagesmith::Apache::Timer::log_handler

LogFormat "%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 (application/x-compressed, 2.8 KB) - not displayed
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.