Hi,
Over the past few weeks we’ve been trying to diagnose severe performance
bottlenecks in our JRuby on Rails app, which I had originally reported
in
http://jira.codehaus.org/browse/JRUBY-4773. While the fix for 4773 did
improve the situation, the problem did not disappear.
Today we were able to isolate the problem and it seems like it’s due to
nested Erb partial rendering.
Environment: Jruby 1.5.1, Rails 2.3.4 on Centos 5.4 (64 bit), JDK
1.6.0_17
(32 bit), Jruby-Rack 0.9.6 (1 Runtime, Rails in multithreaded mode),
Jetty
6.
The Rails action in question would fetch backend data in around 100ms
and
would then take 2300ms to render the view. The view involved nested
calls to
partials about 3-levels deep with a total of about 150 partial calls per
page.
Serial requests took around 2400ms, concurrent requests (10 at a time)
took
over 25sec. The requests would fetch backend data concurrently, but
would
all block for 25 sec during view rendering and then complete shortly
thereafter.
The profiler (Yourkit) did not show any further information. I tried
profiling with jit.compile.mode=FORCE, but that didn’t help either.
I also tried hooking up Jruby-Prof, but for some reason the
GlobalRuntime
that it was trying to add an EventHook to was not the one that
Jruby-Rack
created (I was using a patched Jruby-Rack 0.9.6 which set the runtime
created by the DefaultRackApplication to be the GlobalRuntime, using
Ruby.useAsGlobalRuntime). Not sure if this was a classloader problem,
didn’t
investigate this further.
When we collapsed all partials into 1 erb template, the response times
dropped to 250 ms for serial requests and 1100ms for concurrent
requests,
more than an order of magnitude faster!
Has anyone seen this before, any idea what might be causing this? Or
have we
got some basic setting wrong?
What tools do you use to investigate such problems?
Thanks!
- Yogi