Модераторы: korob2001, ginnie
  

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> POE обработка 1к http запросов, POE::Component::Clien::HTTP 
:(
    Опции темы
nIkTo
Дата 9.4.2010, 12:59 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 218
Регистрация: 5.7.2007

Репутация: нет
Всего: нет



Обрабатываю  POE::Component::Clien::HTTP список урлов, в среднем список содержит до 1к линков, вот написал такой код :

Код

#!/usr/bin/perl -w
use warnings;
use strict;

use Data::Dumper;
use HTTP::Request;
use POE qw(Component::Client::HTTP);

our $debug = 'yes';
my $domains = load('domains.txt');

POE::Component::Client::HTTP->spawn(
  Alias   => 'ua',
  MaxSize => 204800,
  Timeout => 60,
  Agent   => 'Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1; .NET CLR 1.1.4322)'
);

for my $domain (keys %$domains) {
  init_session($domain);
}

$poe_kernel->run();

sub init_session {
  my $domain = shift;
  
  POE::Session->create(
    inline_states => {
      _start      => \&_sess_start,
      _stop       => \&_sess_stop,
      fetch_page  => \&_page_fetch,
      recv_page   => \&_page_recv
    },
    heap => {
      domain      => $domain,
    }
  );
}

sub _sess_start {
  my ($kernel, $heap) = @_[KERNEL, HEAP];
  my $domain = $heap->{domain};
  debug("_sess_start: started ($domain)\n");
  $kernel->yield('fetch_page');
}

sub _sess_stop {
  my ($kernel, $heap) = @_[KERNEL, HEAP];
  my $domain = $heap->{domain};
  debug("_sess_stop: stopped ($domain)\n");
}

sub _page_fetch {
  my ($kernel, $heap) = @_[KERNEL, HEAP];
  my $domain = $heap->{domain};
  debug("_page_fetch: create request ($domain)\n");
  my $request = HTTP::Request->new(GET => "http://".$domain."/");
  $kernel->post('ua', 'request', 'recv_page', $request);
}

sub _page_recv {
  my ($kernel, $heap) = @_[KERNEL, HEAP];
  my ($request_packet, $response_packet) = @_[ARG0, ARG1];
  my $domain = $heap->{domain};
  my $request = $request_packet->[0];
  my $response = $response_packet->[0];
  my $code = $response->code;
  debug("_page_recv: $domain = $code\n");
  open(FILE, ">pages/[$code]-$domain.html");
  print FILE $response->content;
  close(FILE);
}

sub debug {
  print @_ if $debug eq 'yes';
}

sub load {
  my $file = shift;
  my %domains = ();
  
  open(FILE, $file) || return undef;
  while (<FILE>) {
    chomp();
    $domains{$_} = 0;
  }
  close(FILE);
  
  return \%domains;
}


Скрипт отрабатывает, но успешно обрабатывается только часть списка, остальный возвращаются с ошибкой 500 :
Цитата

Error: Internal Server Error
Cannot connect to domain:80 (connect error 10060: Unknown error) This is a client error, not a server error.


В чём тут проблема затаилась ?

Это сообщение отредактировал(а) nIkTo - 9.4.2010, 13:00
PM   Вверх
nIkTo
Дата 10.4.2010, 12:14 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 218
Регистрация: 5.7.2007

Репутация: нет
Всего: нет



Появился ещё один вариант:
Код

#!/usr/bin/perl
use warnings;
use strict;

use HTTP::Request;
use POE qw(Component::Client::HTTP Component::Client::Keepalive);

my %config = (jobs_max  => 100,
              delay     => 10);

my %data = (domains => load('domains.txt'));

our $debug = 'yes';

my $pool = POE::Component::Client::Keepalive->new(
  'keep_alive'    => 300,
  'max_open'      => 1000,
  'max_per_host'  => 10,
  'timeout'       => 20,
);

POE::Component::Client::HTTP->spawn(
  'Alias'             => 'HTTP_CLIENT',
  'MaxSize'           => 300000,
  'Timeout'           => 300,
  'Agent'             => 'Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1; .NET CLR 1.1.4322)',
  'Streaming'         => 0,
  'FollowRedirects'   => 0,
  'ConnectionManager' => $pool
);

POE::Session->create(
  'inline_states' => {
    '_start'    => \&_sess_start,
    '_stop'     => \&_sess_stop,
    'get_jobs'  => \&_get_jobs,
    'job_done'  => \&_job_done,
  },
  'heap' => {
    config  => \%config,
    data    => \%data,
  }
);

POE::Kernel->run;

sub _sess_start {
  my ($kernel, $heap) = @_[KERNEL, HEAP];
  
  debug("_sess_start: STARTED\n");
  $kernel->yield('get_jobs');
}

sub _sess_stop {
  my ($kernel, $heap) = @_[KERNEL, HEAP];
  
  debug("_sess_stop: STOPPED\n");
}

sub _get_jobs {
  my ($kernel, $heap) = @_[KERNEL, HEAP];
  my $config = $heap->{config};
  my $data = $heap->{data};
  
  if (($difference == $config->{jobs_max}) && (scalar(@{$data->{domains}}) == 0)) {
    $kernel->delay('get_jobs', $config->{delay});
  }
  
  my $difference = $config->{jobs_max} - $kernel->call('HTTP_CLIENT' => 'pending_requests_count');
  debug("_get_jobs: DIFFERENCE $difference\n");
  if ($difference <= 0) {
    debug("_get_jobs: RETURN\n");
    return;
  }

  my @jobs = splice(@{$data->{domains}}, 0, $difference);
  
  foreach my $job (@jobs) {
    my $request = HTTP::Request->new(GET => "http://".$job."/");
    $kernel->post('HTTP_CLIENT' => 'request', 'job_done', $request);
  }
  debug("_get_jobs: ADDED ".scalar(@jobs)."\n");
  debug("_get_jobs: REMAINS ".scalar(@{$data->{domains}})."\n");
}

sub _job_done {
  my ($request_packet, $response_packet) = @_[ARG0, ARG1];
  my $request = $request_packet->[0];
  my $response = $response_packet->[0];
  debug("_job_done: ".$response->code."(".$1.")\n") if $response->base =~/^http:\/\/([a-z0-9-\.]+)\//;
  open(FILE, ">pages/[".$response->code."]-$1.html");
  print FILE $response->content;
  close(FILE);
}

sub debug {
  print @_ if $debug eq 'yes';
}

sub load {
  my $file = shift;
  my @domains = ();
  
  open(FILE, $file) || return undef;
  while (<FILE>) {
    chomp();
    push(@domains, $_);
  }
  close(FILE);
  
  return \@domains;
}



Подскажите какой принцип лучше использовать :
1. Создать 1 сессию и в ней пачками получать и отрабатывать запросы (код тут).
2. Создать множество сессий равное количеству запросов (код в первом посте).

Сам склоняюсь к первому.

Почему оба кода на linux CentOS 5 (This is perl, v5.10.0 built for i386-linux-thread-multi) отрабатывают правильно, а на Windows 7 (This is perl, v5.10.1 built for MSWin32-x86-multi-thread) большая часть приходит с ошибкой 500 =(

Это сообщение отредактировал(а) nIkTo - 10.4.2010, 13:27
PM   Вверх
nagual2
Дата 4.7.2010, 14:28 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 14
Регистрация: 13.6.2009

Репутация: нет
Всего: нет



Я использовал POE щас сделал на mojo но заметил что выше 500 одновременных запросов начинаются пробуксовки ... возможно даже запросы не отправляются ... наверно дело в том как перл работает с сокетами ...
PM MAIL   Вверх
  
Ответ в темуСоздание новой темы Создание опроса
Правила форума "Perl"
korob2001
sharq
  • В этом разделе обсуждаются общие вопросы по языку Perl
  • Если ваш вопрос относится к системному программированию, задавайте его здесь
  • Если ваш вопрос относится к CGI программированию, задавайте его здесь
  • Интерпретатор Perl можно скачать здесь ActiveState, O'REILLY, The source for Perl
  • Справочное руководство "Установка perl-модулей", можно скачать здесь


Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, korob2001, sharq.

 
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | Perl: Общие вопросы | Следующая тема »


 




[ Время генерации скрипта: 0.0456 ]   [ Использовано запросов: 22 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.