2. Background
• Social games built using rails
• Needed to integrate with existing java libraries
• Deployment with mongrel was starting to hurt
• First jruby/rails based game did ≈300,000,000 requests per day
• Generated over a billion requests per day to nosql database
• Non standard rails 3.0 app. No Activerecord. Json views
3. Concurrency Concurrency Concurrency
• Concurrency is 90% why to use jruby
• Ruby GIL effectively means peak cpu utilization 1.5 – 2 cores
• No atomics in ruby, no work on lock free algorithms
• Ruby thread primitives are not enough. Don’t use them in jruby
• Java.util.concurrent makes threading easy (and performant)
• Really good debugging/performance/stress testing tools available in
java
4. What kind of concurrency to expect
• Using ruby primitives limits you. Using mutex/synchronize you will
cap out very quickly and see a lot of threads blocking.
• With java.util.concurrent up to hundreds of threads before blocking
becomes an issue.
• Real world apps will usually eat up all cpu/io before hitting context
switching due to lots of threads.
• Real world non trivial rails app handled 750 requests per second using
80 threads.
5. Ruby world is still not thread safe
• Lots of gems are not thread safe. Usually a jruby specific alternative.
• Rails *might* be thread safe by 4.0
• Many misunderstandings around thread safety of system level calls
• Several layers of IO buffering can happen
• Hard learned lesson from java. If the vm doesn’t make any
guarantees, assume it’s not thread safe
• Things are steadily improving. Rails of all places is leading the way
(but still has a ways to go)
6. Effective use of jruby
• Lots of jruby gems that are thin wrappers around java libraries
• Loading random java library and calling from jruby usually just works
• Many places where the java library is better designed.
• Leverage what java does better, but avoid writing java
• Learn to use java.util.concurrent
• Learn to use thread & heap dumps
• Stay away from rails for now
7. Must use tools
• Thread & heap dumps changed my life. Makes debugging
performance and memory related issues easy
• Visualvm is your friend. Works remotely. Connect to any running
server to get memory stats, thread dumps, etc..
• You can instrument apps with JMX to get real time
performance/memory info. Or you can get at it directly in jruby and
log via regular logs.
8. Java libraries I like
• Netty.io. The java version of eventmachine
• Spymemcached. Because Dalli has a giant mutex around network
calls
• Rjack. Collections of jruby wrappers for common java libraries
• Java logging. Rjack SLF4J + Logback my favorite
• Akka. Actor framework for concurrency
• Guard-jruby-rspec. Makes rspec about as fast as under Cruby
• Apache camel
9. Rants
• Ruby (rails mostly) community spread a lot of bad information
• Many of us simply didn’t know better, so we bought into it
• Processes are not better then threads.
• Thread safe code is not hard if you have the right tools
• Please stop making ruby code thread safe by wrapping everything in a
mutex. If you can’t write a proper thread pool, use Thread.local
instead. I don’t care if you think it’s ugly, at least it’s usable.