#ruby-on-rails #ruby #jruby #httpclient
#ruby-on-rails #ruby #jruby #httpclient
Вопрос:
Я использую ruby httpclient gem для загрузки больших файлов. В идеале я хочу иметь возможность загружать файлы размером до 2 ГБ. Когда я загружаю файлы, я не хочу загружать содержимое файла в память по очевидной причине, поэтому я использую get_content API HttpClient следующим образом, а затем записываю фрагменты, которые передаются в блок, в файл,
HTTPClient.new.get_content(url) do |chunk|
puts "Downloaded chunk of size #{chunk.size}"
file.write(chunk)
end
Это очень медленно. Файл размером 10 МБ может легко занять 30 секунд.
Вставляемый блок продолжает выводить размер блока следующим образом,
Downloaded chunk of size 12276
Downloaded chunk of size 4108
Downloaded chunk of size 12276
Downloaded chunk of size 4108
Downloaded chunk of size 12276
Downloaded chunk of size 4108
Downloaded chunk of size 12276
Downloaded chunk of size 4108
Downloaded chunk of size 12276
Если вы посмотрите на размер блока 4108/12276, кажется, что это может быть проблемой. Размеры блоков действительно малы. Я не мог понять, как увеличить размеры блоков.
Я использовал Patron, который основан на libcurl, и он довольно быстр при загрузке, но я пока не слишком заинтересован в том, чтобы вводить зависимость от libcurl.
Как я могу ускорить загрузку HttpClient?
ОБНОВЛЕНИЕ 27.10.2011
Я попробовал два предложения от @NaHi, и вот что я нашел.
Когда я установил для параметра transparent_gzip_decompression значение true, я получил следующее исключение
Zlib::StreamError: stream error: invalid window bits
from /Users/<user>/.rvm/gems/jruby-1.6.2@share/gems/httpclient-2.2.0.2/lib/httpclient/session.rb:652:in `get_body'
from /Users/<user>/.rvm/gems/jruby-1.6.2@share/gems/httpclient-2.2.0.2/lib/httpclient.rb:1062:in `do_get_block'
from /Users/<user>/.rvm/gems/jruby-1.6.2@share/gems/httpclient-2.2.0.2/lib/httpclient.rb:866:in `do_request'
from /Users/<user>/.rvm/gems/jruby-1.6.2@share/gems/httpclient-2.2.0.2/lib/httpclient.rb:953:in `protect_keep_alive_disconnected'
from /Users/<user>/.rvm/gems/jruby-1.6.2@share/gems/httpclient-2.2.0.2/lib/httpclient.rb:865:in `do_request'
from /Users/<user>/.rvm/gems/jruby-1.6.2@share/gems/httpclient-2.2.0.2/lib/httpclient.rb:938:in `follow_redirect'
from /Users/<user>/.rvm/gems/jruby-1.6.2@share/gems/httpclient-2.2.0.2/lib/httpclient.rb:577:in `get_content'
Когда я установил заголовок в ‘Accept-Encoding’ => ‘gzip, deflate’, я увидел улучшение производительности. Файл размером 7296502 байта, который ранее занимал 24 секунды, теперь занимает 16 секунд. Так что это помогает. Для сравнения, однако patron загружает тот же файл за 1,5 секунды. Так что я все еще далек от достижения такой же производительности с httpclient.
Комментарии:
1. httpclient выдает фрагменты ответа на основе HTTP-ответа от сервера. Вы не можете изменить размер блока… Если Patron / curl работает хорошо, может помочь добавление {‘Accept-Encoding’ => ‘gzip,deflate’} в качестве дополнительного HTTP-заголовка. Установка HttpClient#:transparent_gzip_decompression = true также может помочь.
2. Спасибо за попытку. Я исправил ошибку Zlib на стороне JRuby, и transparent_gzip_decompression должен работать с jruby / 1.6.5 (последняя версия). Интересно отличие Perf от patron… Чистый Ruby httpclient должен быть немного медленнее, но x10 медленнее неожиданно. Можете ли вы сообщить мне URL, который вы используете?
3. @NaHi Я попробовал transparent_gzip_compression с помощью JRuby 1.6.5, теперь я не получаю никаких исключений, но эта опция не оказывает положительного влияния на скорость загрузки. URL, который я использую, взят из пользовательского сервиса Java, который находится в разработке и работает на сервере Jetty.
4. как быстро он загружается, если вы удалите
puts
строку из своего блока?