контекст:
Я делаю робот, чтобы прочитать блок новостей на первой странице Google
Результаты. Мне нужны результаты для 200 поисковых запросов (полностью необходимо
читать 200 страниц).
Чтобы избежать блокировки Google, нужно подождать некоторое время, чтобы сделать следующий
поиск (с того же ip). Если вы будете ждать 30 секунд между каждым
поиск, чтение 200 страниц, которые он займет (200 * 30/60) = 1h40m.
Но так как новости о результатах Google меняются очень быстро, мне нужны эти 200
страницы доступны почти одновременно. Так что читая все 200 страниц
должно занять всего несколько минут.
Если работа будет разделена между 20 прокси (ips), она займет (200/20 *
30/60) = 5 м (20 прокси работают одновременно)
Я планировал использовать Pthreads через клик
Вопрос / Сомнение:
Можно ли одновременно запустить 20 потоков? Желательно ли запускать только несколько стволов?
Что если я хочу запустить 100 потоков (используя 100 прокси)?
Какие еще варианты у меня есть?
редактировать:
Я нашел другой вариант, используя php curl_multi или множество библиотек, написанных поверх curl_multi для этого. Но я думаю, что буду придерживаться pthreads.
Некоторые аппаратные средства имеют более 20 ядер, в этих случаях это не просто.
Если на вашем оборудовании менее 20 ядер, это все же не смешное количество потоков, учитывая, что природа потоков будет означать, что они проводят некоторое время, блокируя ожидание ввода-вывода, и намного больше целенаправленно спят, чтобы вы могли не зли Google.
Обычно, когда используемая модель потоков равна 1: 1, как и в PHP, в общем случае рекомендуется составлять расписание для стольких потоков, сколько у вас ядер, это разумное общее правило.
Очевидно, что программное обеспечение, которое было запущено до вас (всей вашей операционной системы), вероятно, уже запланировало гораздо больше потоков, чем у вас есть ядра.
В лучшем случае все еще говорится, что вы не можете выполнять больше потоков одновременно, чем у вас есть доступные ядра, что является причиной общего правила. Однако многим потокам операционных систем на самом деле не нужно работать одновременно, поэтому авторы этих служб не придерживаются тех же правил.
Подобно тем потокам, которые запускает операционная система, вы намерены запретить одновременное выполнение потоков специально, поэтому вы также можете изменить правила.
TL; DR, да, я думаю, что все в порядке.
Обычно это может быть немного глупо.
Но так как вы планируете заставить потоки спать в течение длительного времени между запросами, здесь может быть все в порядке.
Обычно не следует ожидать, что большее количество потоков соответствует большей пропускной способности. Тем не менее, в этом случае это означает, что вы можете использовать больше исходящих адресов проще, спя в течение меньшего времени в целом.
Ваша операционная система имеет жесткие ограничения на количество потоков, которые она позволяет вам создавать, возможно, вы приближаетесь к этим ограничениям на обычном оборудовании в 100 потоков.
TL; DR в этом случае, я думаю, что все в порядке.
Если бы не параметры вашей работы; что вам нужно поспать между запросами и использовать определенные интерфейсы или прокси для маршрутизации запросов по нескольким адресам, вы можете довольно легко использовать неблокирующий ввод / вывод.
Даже учитывая параметры, вы все равно могли бы использовать неблокирующий ввод / вывод, но это сделало бы программирование задачи намного более сложным, чем это необходимо.
По моему (возможно, предвзятому) мнению, вам лучше использовать потоки, решение будет более простым, с меньшим запасом на ошибку и более легким для понимания, когда вы вернетесь к нему через 6 месяцев (когда оно сломается, потому что Google изменил их разметку или без разницы).
Использование прокси-серверов может оказаться ненадежным и медленным, если для некоторых приложений это является основной функцией, рассмотрите возможность получения достаточного количества IP-адресов, чтобы вы могли самостоятельно направлять эти запросы с использованием определенных интерфейсов. cURL, параметры контекста и сокеты позволят вам установить исходящий адрес, это, вероятно, будет намного надежнее и быстрее.
Хотя скорость не обязательно беспокоит, надежность должна быть. Разумно, чтобы машина была связана с 20 адресами, менее разумно, чтобы она была связана с 100 адресами, но если это необходимо.
Почему бы вам просто не сделать один цикл, который проходит через прокси?
Таким образом, это всего лишь один процесс за раз, а также вы можете отфильтровывать мертвые прокси, и при этом вы можете получать желаемую частоту обновлений.
Вы могли бы сделать что-то вроде этого:
$proxies=array('127.0.0.1','192.168.1.1'); // define proxies
$dead=array(); // here you can store which proxies went dead (slow, not responding, up to you)
$works=array('http://google.com/page1','http://google.com/page2'); // define what you want to do
$run=true; $last=0; $looptime=(5*60); // 5 minutes update
$workid=0; $proxyid=0;
while ($run)
{
if ($workid<sizeof($works))
{ // have something to do ...
$work=$works[$workid]; $workid++; $success=0;
while (($success==0)and($proxyid<sizeof($proxies)))
{
if (!in_array($proxyid,$dead))
{
$proxy=$proxies[$proxyid];
$success=launch_the_proxy($work,$proxy);
if ($success==0) {if (!in_array($proxyid,$dead)) {$dead[]=$proxyid;}}
}
$proxyid++;
}
}
else
{ // restart the work sequence once there's no more work to do and loop time is reached
if (($last+$looptime)<time()) {$last=time(); $workid=0; $proxyid=0;}
}
sleep(1);
}
Обратите внимание, это простой пример, вы должны работать над деталями. Вы также должны иметь в виду, что для этого требуется как минимум равное количество прокси по сравнению с работой. (вы можете настроить это позже, как пожелаете, но для этого потребуется более сложный способ определить, какой прокси можно использовать снова)