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
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 injava
What kind of concurrency to expect• Using ruby primitives limits you. Using mutex/synchronize you willcap out very quickly and see a lot of threads blocking.• With java.util.concurrent up to hundreds of threads before blockingbecomes an issue.• Real world apps will usually eat up all cpu/io before hitting contextswitching due to lots of threads.• Real world non trivial rails app handled 750 requests per second using80 threads.
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 anyguarantees, 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)
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
Must use tools• Thread & heap dumps changed my life. Makes debuggingperformance and memory related issues easy• Visualvm is your friend. Works remotely. Connect to any runningserver to get memory stats, thread dumps, etc..• You can instrument apps with JMX to get real timeperformance/memory info. Or you can get at it directly in jruby andlog via regular logs.
Java libraries I like• Netty.io. The java version of eventmachine• Spymemcached. Because Dalli has a giant mutex around networkcalls• 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
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 amutex. If you can’t write a proper thread pool, use Thread.localinstead. I don’t care if you think it’s ugly, at least it’s usable.