使用AnyEvent的perl脚本速度不够快

时间:2017-04-20 18:43:39

标签: perl http anyevent

这是我创建的用于从包含URL列表的文件执行HTTP事务的小脚本。问题是它无法像我希望的那样快地进行HTTP事务。更确切地说,我将速率设置为200 /秒,但它只能以大约50 /秒的速度发送。服务器足够强大,可以处理100秒/秒。

这是在运行Ubuntu 14.04桌面的E5-1650 CPU和64GB RAM的功能强大的PC上运行的。脚本运行时,CPU使用率仅为12%左右。我使用的命令是perl httpStresser.pl urlList rate 200

知道为什么吗?

use AnyEvent;
use EV;
use AnyEvent::HTTP;
use AnyEvent::Handle;
use Time::HiRes qw( gettimeofday );
my $expectedRespCode = 200;
my $rate = 1;
my @urls = ();
readUrls(shift);
my $numOfUrls = $#urls;
my $start = time();
my $printed = 0; #have we printed the completion msg.
my $gId = 0;

my $spawned;
my @ctx = ();
my $i;

for ($i=0; $i<=$#ARGV; $i++) {
    if ($ARGV[$i] =~ /^expect/) {
        $expectedRespCode = $ARGV[$i+1];
        $i++;
    } elsif ($ARGV[$i] =~ /^rate/) {
        $rate = $ARGV[$i+1];
        print "rate is now $rate\n";
        $i++;
    } elsif ($ARGV[$i] =~ /^skip/) {
        $gId = $ARGV[$i+1];
        $i++;
    } else {
        die "only max, stayup are supported\n";
    } 
}
my $spawned = 0;
my $w = AnyEvent->condvar;
$| = 1;
my $start = getTS();
my $_timer;
$_timer = AnyEvent->timer(after => 0, interval => 0.001, cb => ::timeoutHandler);
$w->recv;

sub kickoff {
    my $id = $gId ++;
    if ($id > $numOfUrls) { 
        if ($printed == 0) {
            print "done!!\n"; $printed = 1;
        }
        return;
    }
    #print "$id\n";
    http_get $urls[$id], headers => { }, sub { 
        my $statusCode = $_[1]->{Status};
        #printf "status $statusCode %d\n", time() - $start;
        if (($id % 100) == 0) {
            print "$id\n";
        }
        if ($statusCode != $expectedRespCode) {
            print "unexpected resp code $id:$statusCode $urls[$id]\n";
        }
    };
}

sub timeoutHandler {
    #print time(), "|\n";
    if (! defined $start) {
        $start = getTS(); kickoff(); $spawned = 1; return;
    }
    my $delta = getTS() - $start;
    my $target = $delta * $rate;
    #printf "%.4f %4d $spawned\n", $delta, $target;
    for (; $spawned <= $target; $spawned++) {
        kickoff();
    }
    if ($delta >= 1.0 ) {
        $start += 1.0; $spawned = 0;
    }
}

sub readUrls {
    my $fname = shift;
    my $line;
    open FD, $fname || die "Failed to open $fname $!\n";
    while (<FD>) {
        chomp($line = $_);
        push @urls, $line;
    }
    close FD;
}

sub getTS {
    my ($seconds, $microseconds) = gettimeofday;
    return $seconds + (0.0+ $microseconds)/1000000.0;
}

0 个答案:

没有答案