Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Migrate to JRuby

17bca47a4961a24f82ef972aa9e1c986?s=47 Ian Yang
November 06, 2013

Migrate to JRuby

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

17bca47a4961a24f82ef972aa9e1c986?s=128

Ian Yang

November 06, 2013
Tweet

Transcript

  1. Migrate to JRuby What We Learned

  2. ian yang @doitian

  3. Agenda • Background • How to Migrate • What We

    Learned
  4. Background

  5. Breadcrumb Payments

  6. The Codebase • 4 Ruby on Rails applications • Ruby

    1.9.2 and Rails 3.2.1
  7. Why JRuby? • Multithreading • Memory Leak • Easy integration

    of libraries on JVM
  8. How to Migrate

  9. Choose a Deploy Strategy

  10. Warbler Trinidad TorqueBox Archive File ✔ ✔ ✔ Capistrano ✔

    ✔ Scheduler ✔ ✔ Background Jobs ✔ ✔ Clustering ✔
  11. Warbler Trinidad TorqueBox Archive File ✔ ✔ ✔ Capistrano ✔

    ✔ Scheduler ✔ ✔ Background Jobs ✔ ✔ Clustering ✔
  12. JRuby-Lint https://github.com/jruby/jruby-lint

  13. What We Learned

  14. Gems Alternatives

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

  16. Lock Compatible Version

  17. gem 'rubyzip', '<1.0.0'

  18. *nix to JVM

  19. • No Kernel#fork • Cannot trap all signals

  20. Kernel#fork → Thread.new

  21. Thread-safety

  22. Avoid Sharing Mutable State Between Threads

  23. Global Variable ⾠ Class Variable ⾠ Class Instance Variable ⾠

  24. Lazy Initialization → Preload

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

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

    r end end ! # config/initializers/cvv.rb Cvv.redis = Redis.new(...) ✔
  27. Thread Local Storage

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

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

    s end end ✔
  30. Atomic Variable

  31. class Airlock class_variable :enabled end ✘

  32. # gem 'atomic'! class Airlock! @@enabled = Atomic.new(false)! def self.enabled!

    @@enabled.value! end! def self.enabled=(e)! @@enabled.update { e }! end! end ✔
  33. Locks require 'thread'! mutex = Mutex.new! ! Thread.new do! mutex.synchronize

    do! ...! end! end
  34. Reference: Concurrency in JRuby https://github.com/jruby/jruby/wiki/Concurrency-in- jruby

  35. Reference: Ruby Mutithreading http://www.tutorialspoint.com/ruby/ ruby_multithreading.htm

  36. Resque

  37. • No Fork • Jobs run in the same process

    • Free the resources
  38. OpenSSL

  39. Full OpenSSL Support gem 'jruby-openssl'

  40. Different Cryptography Implementations https://github.com/jruby/jruby/issues/931

  41. None
  42. Cryptography Adapter • Use OpenSSL in CRuby • Use JCE

    directly in JRuby (java_import)
  43. Tuning

  44. TorqueBox + JBoss

  45. Connection Pool Size

  46. Thread Pool Size

  47. JVM Memory

  48. How To? • Benchmark • Monitoring

  49. References

  50. Deploying with JRuby

  51. JRuby Wiki https://github.com/jruby/jruby/wiki

  52. None