Я пытаюсь загрузить более 1 млн страниц (URL-адреса заканчиваются идентификатором последовательности). Я реализовал многоцелевой менеджер загрузок с настраиваемым количеством потоков загрузки и одним потоком обработки. Загрузчик загружает файлы в пакетном режиме:
curl = Curl::Easy.new
batch_urls.each { |url_info|
curl.url = url_info[:url]
curl.perform
file = File.new(url_info[:file], "wb")
file << curl.body_str
file.close
# ... some other stuff
}
Я попытался загрузить образец 8000 страниц. При использовании кода выше я получаю 1000 за 2 минуты. Когда я записываю все URL в файл и делаю в оболочке:
cat list | xargs curl
Я генерирую все 8000 страниц за две минуты.
Дело в том, что мне нужно, чтобы оно было в коде ruby, потому что есть другой код для мониторинга и обработки.
Я пытался:
- Curl :: Multi - как-то быстрее, но пропускает 50-90% файлов (не загружает их и не дает причины / кода)
- несколько нитей с помощью Curl :: Easy - примерно с той же скоростью, что и однопоточная
Почему повторно используется Curl :: Easy медленнее, чем последующие вызовы curl из командной строки, и как я могу сделать это быстрее? Или что я делаю не так?
Я бы предпочел исправить код менеджера загрузок, чем выполнять загрузку для этого случая другим способом.
До этого я вызывал wget из командной строки, который мне предоставил файл со списком URL. Однако не все ошибки были обработаны, также не удалось указать выходной файл для каждого URL отдельно при использовании списка URL.
Теперь мне кажется, что лучшим способом было бы использовать несколько потоков с системным вызовом команды 'curl'. Но почему, когда я могу напрямую использовать Curl в Ruby?
Код для диспетчера загрузки здесь, если он может помочь: Диспетчер загрузки (я играл с тайм-аутами, не устанавливая его в различные значения, он не помог)
Любые подсказки приветствуются.