Migrate to JRuby

52
Migrate to JRuby What We Learned

description

My Talk on Ruby Conf China 2013, experience about how we migrate Ruby on Rails project to JRuby in Groupon Payments.

Transcript of Migrate to JRuby

Page 1: Migrate to JRuby

Migrate to JRubyWhat We Learned

Page 3: Migrate to JRuby

Agenda

• Background

• How to Migrate

• What We Learned

Page 4: Migrate to JRuby

Background

Page 5: Migrate to JRuby

Breadcrumb Payments

Page 6: Migrate to JRuby

The Codebase

• 4 Ruby on Rails applications

• Ruby 1.9.2 and Rails 3.2.1

Page 7: Migrate to JRuby

Why JRuby?

• Multithreading

• Memory Leak

• Easy integration of libraries on JVM

Page 8: Migrate to JRuby

How to Migrate

Page 9: Migrate to JRuby

Choose a Deploy Strategy

Page 10: Migrate to JRuby

Warbler Trinidad TorqueBox

Archive File ✔ ✔ ✔

Capistrano ✔ ✔

Scheduler ✔ ✔

Background Jobs ✔ ✔

Clustering ✔

Page 11: Migrate to JRuby

Warbler Trinidad TorqueBox

Archive File ✔ ✔ ✔

Capistrano ✔ ✔

Scheduler ✔ ✔

Background Jobs ✔ ✔

Clustering ✔

Page 12: Migrate to JRuby

JRuby-Lint

https://github.com/jruby/jruby-lint

Page 13: Migrate to JRuby

What We Learned

Page 14: Migrate to JRuby

Gems Alternatives

Page 15: Migrate to JRuby

Wiki: C Extension Alternatives

https://github.com/jruby/jruby/wiki/C-Extension-Alternatives

Page 16: Migrate to JRuby

Lock Compatible Version

Page 17: Migrate to JRuby

gem 'rubyzip', '<1.0.0'

Page 18: Migrate to JRuby

*nix to JVM

Page 19: Migrate to JRuby

• No Kernel#fork

• Cannot trap all signals

Page 20: Migrate to JRuby

Kernel#fork → Thread.new

Page 21: Migrate to JRuby

Thread-safety

Page 22: Migrate to JRuby

Avoid Sharing Mutable State Between Threads

Page 23: Migrate to JRuby

Global Variable ⚠Class Variable ⚠

Class Instance Variable ⚠

Page 24: Migrate to JRuby

Lazy Initialization → Preload

Page 25: Migrate to JRuby

class Cvv def self.redis @@redis ||= Redis.new(...) end end

Page 26: Migrate to JRuby

class Cvv def self.redis @@redis end def self.redis=(r) @@redis = r end end !

# config/initializers/cvv.rb Cvv.redis = Redis.new(...)

Page 27: Migrate to JRuby

Thread Local Storage

Page 28: Migrate to JRuby

class Processor class_attribute :skip ! def execute do_something unless self.class.skip end end

Page 29: Migrate to JRuby

class Processor def self.skip Thread.current['Processor.skip'] end def self.skip=(s) Thread.current['Processor.skip'] = s end end

Page 30: Migrate to JRuby

Atomic Variable

Page 31: Migrate to JRuby

class Airlock class_variable :enabled end

Page 32: Migrate to JRuby

# gem 'atomic'!class Airlock! @@enabled = Atomic.new(false)! def self.enabled! @@enabled.value! end! def self.enabled=(e)! @@enabled.update { e }! end!end

Page 33: Migrate to JRuby

Locks

require 'thread'!mutex = Mutex.new!!

Thread.new do! mutex.synchronize do! ...! end!end

Page 34: Migrate to JRuby

Reference: Concurrency in JRuby

https://github.com/jruby/jruby/wiki/Concurrency-in-jruby

Page 35: Migrate to JRuby

Reference: Ruby Mutithreading

http://www.tutorialspoint.com/ruby/ruby_multithreading.htm

Page 36: Migrate to JRuby

Resque

Page 37: Migrate to JRuby

• No Fork

• Jobs run in the same process

• Free the resources

Page 38: Migrate to JRuby

OpenSSL

Page 39: Migrate to JRuby

Full OpenSSL Support

gem 'jruby-openssl'

Page 40: Migrate to JRuby

Different Cryptography Implementations

https://github.com/jruby/jruby/issues/931

Page 41: Migrate to JRuby
Page 42: Migrate to JRuby

Cryptography Adapter

• Use OpenSSL in CRuby

• Use JCE directly in JRuby (java_import)

Page 43: Migrate to JRuby

Tuning

Page 44: Migrate to JRuby

TorqueBox + JBoss

Page 45: Migrate to JRuby

Connection Pool Size

Page 46: Migrate to JRuby

Thread Pool Size

Page 47: Migrate to JRuby

JVM Memory

Page 48: Migrate to JRuby

How To?

• Benchmark

• Monitoring

Page 49: Migrate to JRuby

References

Page 50: Migrate to JRuby

Deploying with JRuby

Page 51: Migrate to JRuby

JRuby Wiki

https://github.com/jruby/jruby/wiki

Page 52: Migrate to JRuby