Загрузка большого количества файлов в моем веб-приложении приводит к тупику в Rack + Unicorn - PullRequest
1 голос
/ 01 июня 2011

У меня есть приложение Rails 3.1rc1, которое позволяет загружать несколько файлов одновременно через плагин jQuery, называемый «Загрузка файла»: http://aquantum -demo.appspot.com / file-upload Это позволяет Пользователь может загрузить кучу изображений, размер которых я затем изменю, обработав команду ImageMagick convert и загрузить на S3. Мой сайт обслуживается двумя работниками Единорога.

Прошлой ночью я загружал серию из примерно 30 изображений одновременно. Похоже, что Chrome будет делать 6 одновременно, и он прошел примерно половину пакета, прежде чем это начало появляться в моем unicorn.stderr.log:

E, [2011-06-01T07:01:39.806164 #21751] ERROR -- : Read error: #<ThreadError: deadlock; recursive locking>
E, [2011-06-01T07:01:39.806316 #21751] ERROR -- : /var/www/shared/bundle/ruby/1.9.1/gems/rack-1.3.0/lib/rack/lock.rb:33:in `lock'
/var/www/shared/bundle/ruby/1.9.1/gems/rack-1.3.0/lib/rack/lock.rb:33:in `call'
/var/www/shared/bundle/ruby/1.9.1/gems/rack-cache-1.0.2/lib/rack/cache/context.rb:132:in `forward'
/var/www/shared/bundle/ruby/1.9.1/gems/rack-cache-1.0.2/lib/rack/cache/context.rb:243:in `fetch'
/var/www/shared/bundle/ruby/1.9.1/gems/rack-cache-1.0.2/lib/rack/cache/context.rb:181:in `lookup'
/var/www/shared/bundle/ruby/1.9.1/gems/rack-cache-1.0.2/lib/rack/cache/context.rb:65:in `call!'
/var/www/shared/bundle/ruby/1.9.1/gems/rack-cache-1.0.2/lib/rack/cache/context.rb:50:in `call'
/var/www/shared/bundle/ruby/1.9.1/gems/railties-3.1.0.rc1/lib/rails/rack/content_length.rb:16:in `call'
/var/www/shared/bundle/ruby/1.9.1/gems/hoptoad_notifier-2.4.10/lib/hoptoad_notifier/user_informer.rb:12:in `call'
/var/www/shared/bundle/ruby/1.9.1/gems/railties-3.1.0.rc1/lib/rails/engine.rb:438:in `call'
/var/www/shared/bundle/ruby/1.9.1/gems/railties-3.1.0.rc1/lib/rails/railtie/configurable.rb:28:in `method_missing'
/var/www/shared/bundle/ruby/1.9.1/gems/unicorn-3.6.2/lib/unicorn/http_server.rb:545:in `process_client'
/var/www/shared/bundle/ruby/1.9.1/gems/unicorn-3.6.2/lib/unicorn/http_server.rb:623:in `block in worker_loop'
/var/www/shared/bundle/ruby/1.9.1/gems/unicorn-3.6.2/lib/unicorn/http_server.rb:621:in `each'
/var/www/shared/bundle/ruby/1.9.1/gems/unicorn-3.6.2/lib/unicorn/http_server.rb:621:in `worker_loop'
/var/www/shared/bundle/ruby/1.9.1/gems/unicorn-3.6.2/lib/unicorn/http_server.rb:509:in `block (2 levels) in spawn_missing_workers'
/var/www/shared/bundle/ruby/1.9.1/gems/unicorn-3.6.2/lib/unicorn/http_server.rb:507:in `fork'
/var/www/shared/bundle/ruby/1.9.1/gems/unicorn-3.6.2/lib/unicorn/http_server.rb:507:in `block in spawn_missing_workers'
/var/www/shared/bundle/ruby/1.9.1/gems/unicorn-3.6.2/lib/unicorn/http_server.rb:503:in `each'
/var/www/shared/bundle/ruby/1.9.1/gems/unicorn-3.6.2/lib/unicorn/http_server.rb:503:in `spawn_missing_workers'
/var/www/shared/bundle/ruby/1.9.1/gems/unicorn-3.6.2/lib/unicorn/http_server.rb:516:in `maintain_worker_count'
/var/www/shared/bundle/ruby/1.9.1/gems/unicorn-3.6.2/lib/unicorn/http_server.rb:166:in `start'
/var/www/shared/bundle/ruby/1.9.1/gems/unicorn-3.6.2/lib/unicorn.rb:30:in `run'
/var/www/shared/bundle/ruby/1.9.1/gems/unicorn-3.6.2/bin/unicorn:120:in `<top (required)>'
/var/www/shared/bundle/ruby/1.9.1/bin/unicorn:19:in `load'
/var/www/shared/bundle/ruby/1.9.1/bin/unicorn:19:in `<main>'

Время загрузки остальных изображений истекло, и Unicorn перезапустил себя. Я мог загрузить снова, но выполнение нескольких операций сразу же вызывало эту ошибку (и гораздо чаще после того, как это произошло в первый раз - иногда я мог завести ее в тупик при загрузке двух файлов одновременно).

Я надеюсь на некоторые идеи относительно того, с чего начать устранение неполадок. Какая часть запроса находится в тупике? Ни один из моих Rails-кодов не показывается где-либо в этом стеке, поэтому я предполагаю, что это происходит в логике хардкорных запросов, что заставляет меня думать, что это будет нелегко. Должен ли я вернуться к чему-то менее управляемому событиями, как Mongrel для загрузки файлов? Я предполагаю, что это означает, что вы сможете загрузить только столько файлов одновременно, сколько есть экземпляров mongrel, но, по крайней мере, весь сайт не выйдет из строя, если кто-то загрузит огромную партию файлов (что, я надеюсь, будет быть обычным явлением).

Спасибо за любую помощь!

Обновление Я вижу, что команда ImageMagick convert довольно часто блокируется ... Я не уверен, как работают внутренние компоненты Rack, когда вы получили запрос, который "завис" сервер. Я собираюсь переключиться на freeimage и посмотреть, что произойдет. Я также собираюсь взглянуть на Rainbows! в качестве альтернативы Unicorn на странице загрузки, поскольку это длительные запросы, которые Unicorn признает, что они не очень хороши.

1 Ответ

0 голосов
/ 01 июня 2011

Вам нужно настроить плагин загрузки jQuery для загрузки по одному файлу за раз (возможно, насколько я помню, с этим плагином). Это не проблема Google Chrome.

Также используйте некоторую фоновую работу для обработки изображений (например, delayed_job или resque)

В качестве заключительного замечания: если вы планируете, что ваш сайт получит массу загрузок, возможно, вам следует перейти на какой-либо внешний сервис для обработки мультимедиа (например, мы используем transloadit.com для проекта, над которым я работаю).

UPDATE: Я нашел эту ошибку о стойке: https://github.com/rack/rack/issues/87

также нашел ваш ответ на github;) https://github.com/rack/rack/issues/183

ты это решил?

...