Производительность приложения sinatra на jruby
У меня есть приложение sinatra, которое работает значительно медленнее, чем хотелось бы. Моим первым подозрением является то, что узким местом является мой собственный код, поэтому я извлек его в автономный скрипт бенчмаркинга.
THREADS = 100
ITERATIONS = 1
def make_calls
ITERATIONS.times do
# ... my stuff here
end
end
1.upto(THREADS) do |n|
Benchmark.bm do |bm|
threads = []
n.times do
threads << Thread.new { make_calls }
end
bm.report("#{n} threads:") { threads.each { |t| t.value } }
end
end
Где make_calls вызывает мой собственный код. Я рад сообщить, что к тому времени, когда мы достигли 100 потоков, совокупное время make_calls во всех потоках составляет 0,6 секунды, что достаточно быстро для моих целей. Причина, по которой я обертываю метод make_calls в приведенные выше потоки, заключается в том, что в моем собственном коде используются потоки (нативные потоки java через java.concurrent.FixedThreadPool(500)) /ExecutorService, и я хотел убедиться, что это хорошо работает в среде, которая потенциально использует другие модели потоков. Одна итерация в одном потоке выполняется примерно за 0,02 секунды после разогрева jruby.
Таким образом, вышесказанное хорошо, но когда я добавляю это на веб-сервер sinatra со следующим:
require 'sinatra'
get '/' do
# ... my stuff here
end
Время ответа на запрос к этой конечной точке составляет примерно 5 секунд. - Увеличьте количество одновременных запросов, и время ответа возрастает линейным образом. Я использовал и Jetty-Rackup, и Тринидад, чтобы попробовать это, используя Jruby 1.7 на Linux и Solaris.
Я пытался оптимизировать экземпляр Тринидада безрезультатно (максимальное / минимальное время выполнения и т. Д.). Наилучшая производительность, которую мы видели, это запуск любого сервера в потоке! режим, и оба сервера показывают сравнительную производительность в этом режиме.
Может кто-нибудь объяснить мне, где расходуется время или как улучшить эту настройку?
1 ответ
Не похоже, что сервер является ограничивающим фактором. Возможно это проблема со стойкой или синатрой, но
# ... my stuff here
на самом деле мало что дает. Попробуйте использовать инструмент профилирования (с самого начала можно использовать VisualVM), чтобы проверить, выделяете ли вы массу ненужных вам объектов, ожидают ли все ваши потоки и т. Д., Затем измените или устраните то, что вы считаете узким местом.
Повторите это, пока вы не думаете, что это достаточно быстро;)