Параллелизм в стойке - rack.multithread, async.callback или оба?

Я пытаюсь полностью понять возможности одновременной обработки запросов в Rack. Я использовал async_sinatra для создания приложения с длительным опросом, и сейчас я экспериментирую с голым железом Rack, используя throw: async и / или флаг Thin --threaded. Мне нравится эта тема, но есть некоторые вещи, которые я просто не понимаю. (Нет, я не путаю параллелизм с параллелизмом, и да, я понимаю ограничения, налагаемые GIL.)

Q1. Мои тесты показывают, что thin --threaded (т.е. rack.multithread = true ) запускает запросы одновременно в отдельных потоках (я предполагаю, что с использованием EM), то есть длительный запрос A не будет блокировать запрос B (IO в сторону). Это означает, что моему приложению не требуется никакого специального кодирования (например, обратных вызовов) для достижения параллелизма (опять же, игнорирование блокирующих вызовов БД, ввода-вывода и т. Д.). Это то, что, как мне кажется, я наблюдал - это правильно?

Q2. Существует еще один, более часто обсуждаемый способ достижения параллелизма, включающий EventMachine.defer и throw: async . Строго говоря, запросы не обрабатываются с помощью потоков. Они обрабатываются последовательно, но всю тяжелую работу и обратный вызов передают в EventMachine, который использует async.callback для отправки ответа в более позднее время. После того, как запрос A выгружает свою работу в EM.defer, запускается запрос B. Это правильно?

Q3. Если предположить, что вышеизложенное более или менее верно, есть ли какое-то конкретное преимущество у одного метода перед другим? Очевидно - многопоточный выглядит как волшебная пуля. Есть ли минусы? Если нет, то почему все говорят об async_sinatra / throw: async / async.callback ? Возможно, первое звучит так: «Я хочу сделать мое приложение Rails более быстрым при большой нагрузке», а второе лучше подходит для приложений с большим количеством длительных запросов? Или, может быть, масштаб является фактором? Просто догадываюсь.

Я использую Thin 1.2.11 на MRI Ruby 1.9.2. (К вашему сведению, я должен использовать флаг - no-epoll , так как существует давняя, предположительно решенная, но не совсем проблема с использованием EventMachine epoll и Ruby 1.9.2. Это не относится к делу, но любое понимание приветствуется.)

35
задан zed_0xff 20 December 2011 в 17:08
поделиться