Migrate to JRuby

558 views

Published on

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

Published in: Technology
0 Comments
0 Likes
Statistics
Notes
  • Be the first to comment

  • Be the first to like this

No Downloads
Views
Total views
558
On SlideShare
0
From Embeds
0
Number of Embeds
2
Actions
Shares
0
Downloads
4
Comments
0
Likes
0
Embeds 0
No embeds

No notes for slide

Migrate to JRuby

  1. 1. Migrate to JRuby What We Learned
  2. 2. ian yang @doitian
  3. 3. Agenda • Background • How to Migrate • What We Learned
  4. 4. Background
  5. 5. Breadcrumb Payments
  6. 6. The Codebase • 4 Ruby on Rails applications • Ruby 1.9.2 and Rails 3.2.1
  7. 7. Why JRuby? • Multithreading • Memory Leak • Easy integration of libraries on JVM
  8. 8. How to Migrate
  9. 9. Choose a Deploy Strategy
  10. 10. Archive File Capistrano Scheduler Background Jobs Clustering Warbler ✔ Trinidad ✔ ✔ ✔ ✔ TorqueBox ✔ ✔ ✔ ✔ ✔
  11. 11. Archive File Capistrano Scheduler Background Jobs Clustering Warbler ✔ Trinidad ✔ ✔ ✔ ✔ TorqueBox ✔ ✔ ✔ ✔ ✔
  12. 12. JRuby-Lint https://github.com/jruby/jruby-lint
  13. 13. What We Learned
  14. 14. Gems Alternatives
  15. 15. Wiki: C Extension Alternatives https://github.com/jruby/jruby/wiki/C-ExtensionAlternatives
  16. 16. Lock Compatible Version
  17. 17. gem 'rubyzip', '<1.0.0'
  18. 18. *nix to JVM
  19. 19. • Cannot trap all signals • No Kernel#fork
  20. 20. Kernel#fork → Thread.new
  21. 21. Thread-safety
  22. 22. Avoid Sharing Mutable State Between Threads
  23. 23. Global Variable Class Variable Class Instance Variable
  24. 24. Lazy Initialization → Preload
  25. 25. class Cvv ✘ def self.redis @@redis ||= Redis.new(...) end end
  26. 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. 27. Thread Local Storage
  28. 28. class Processor class_attribute :skip ✘ ! def execute do_something unless self.class.skip end end
  29. 29. ✔ class Processor def self.skip Thread.current['Processor.skip'] end def self.skip=(s) Thread.current['Processor.skip'] = s end end
  30. 30. Atomic Variable
  31. 31. class Airlock class_variable :enabled end ✘
  32. 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. 33. Locks require 'thread'! mutex = Mutex.new! ! Thread.new do! mutex.synchronize do! ...! end! end
  34. 34. Reference: Concurrency in JRuby https://github.com/jruby/jruby/wiki/Concurrency-injruby
  35. 35. Reference: Ruby Mutithreading http://www.tutorialspoint.com/ruby/ ruby_multithreading.htm
  36. 36. Resque
  37. 37. • Jobs run in the same process • Free the resources • No Fork
  38. 38. OpenSSL
  39. 39. Full OpenSSL Support gem 'jruby-openssl'
  40. 40. Different Cryptography Implementations https://github.com/jruby/jruby/issues/931
  41. 41. Cryptography Adapter • Use OpenSSL in CRuby • Use JCE directly in JRuby (java_import)
  42. 42. Tuning
  43. 43. TorqueBox + JBoss
  44. 44. Connection Pool Size
  45. 45. Thread Pool Size
  46. 46. JVM Memory
  47. 47. How To? • Benchmark • Monitoring
  48. 48. References
  49. 49. Deploying with JRuby
  50. 50. JRuby Wiki https://github.com/jruby/jruby/wiki

×