source: lab.git/misc/httpbench.pl @ 178d578

Last change on this file since 178d578 was 178d578, checked in by Ken-ichi Mito <mitty@…>, 10 years ago

new option --duration

  • set loop duration time (second)
    • with --duration, --loops is ignored
  • Property mode set to 100755
File size: 3.0 KB
Line 
1#! /usr/bin/perl -w
2
3use strict;
4use warnings;
5use utf8;
6
7use Getopt::Long qw(:config posix_default no_ignore_case gnu_compat);
8use Parallel::ForkManager;
9use LWP::UserAgent;
10use Time::HiRes qw(sleep gettimeofday);
11
12usage() if (@ARGV == 0);
13
14GetOptions(
15    'h|help'            => \ my $help,
16    'i|inputfile=s'     => \ my $file,
17    'c|concurrency=i'   => \ my $concurrency,
18    'n|loops=i'         => \ my $loops,
19    'd|duration=i'      => \ my $duration,
20    'w|wait=f'          => \ my $wait,
21) or usage();
22
23usage() if $help;
24
25$concurrency ||= 1;
26$loops ||= 1;
27$duration ||= 0;
28$wait ||= 0;
29
30my @urls = file2urls($file) if ($file);
31push @urls, @ARGV;
32
33my $num = scalar @urls;
34my $l = ($duration) ? "$duration seconds loops" : "$loops loops";
35warn "$num urls with $concurrency clients, $l\n";
36warn "Total: ", $num * $concurrency * $loops, " requests\n" if (! $duration);
37warn "wait for $wait second between requests\n" if ($wait);
38
39my $ua = LWP::UserAgent->new(
40    ssl_opts => { verify_hostname => 0 },
41);
42my $transfer = 0;
43my $pm = Parallel::ForkManager->new($concurrency);
44$pm->run_on_finish(
45    sub {
46        my ($pid, $exit_code, $ident, $exit_signal, $core_dump, $dataref) = @_;
47        if (defined $dataref) {
48            $transfer += $$dataref;
49        }
50    }
51);
52
53my ($startsec, $startmicro) = gettimeofday();
54for (my $child = 0; $child < $concurrency; $child++) {
55    use bytes;
56    if ($pm->start) {
57        # parent
58        warn "forks $child/$concurrency child ...\n";
59    }
60    else {
61        # child
62        my $transfer = 0;
63        my $i = 0;
64        while (1) {
65            if ($duration) {
66                last if (time() - $startsec > $duration);
67            }
68            else {
69                last if ($i >= $loops);
70            }
71           
72            print STDERR "processing $i/$loops loop\r";
73            foreach my $url (@urls) {
74                my $res = $ua->get($url);
75                if ($res->is_success) {
76                    $transfer += length($res->content);
77                }
78                else {
79                    print STDERR "\nfail: $url";
80                }
81                sleep($wait);
82            }
83           
84            $i++;
85        }
86        $pm->finish(0, \$transfer);
87    }
88}
89$pm->wait_all_children;
90my ($endsec, $endmicro) = gettimeofday();
91my $elapsed = ($endsec - $startsec) + ($endmicro - $startmicro) / 10**6;
92my $bytepersec = $transfer / $elapsed;
93
94my @units = qw( B/s KiB/s MiB/s GiB/s );
95my $unit = 0;
96while ($bytepersec > 1024) {
97    $bytepersec /= 1024;
98    $unit++;
99}
100$bytepersec = sprintf("%.4g", $bytepersec);
101
102warn "\n ...done.\n";
103warn "get $transfer bytes in $elapsed seconds ($bytepersec $units[$unit])\n";
104
105sub usage {
106    warn "$0 -i urls.txt -c concurrency -n loops -w wait_interval\n",
107         " OR...\n",
108         "$0 url1 url2\n"
109    ;
110   
111    exit;
112}
113
114sub file2urls {
115    my $file = shift;
116   
117    open my $fh, '<', $file or die "$file: $!";
118   
119    my(@urls, $url);
120    while ($url = <$fh>) {
121        chomp $url;
122        push @urls, $url;
123    }
124   
125    return @urls;
126}
Note: See TracBrowser for help on using the repository browser.