Migrate to

JRuby

What We Learned
ian yang
@doitian
Agenda

• Background	

• How to Migrate	

• What We Learned
Background
Breadcrumb Payments
The Codebase

• 4 Ruby on Rails applications	

• Ruby 1.9.2 and Rails 3.2.1
Why JRuby?

• Multithreading	

• Memory Leak	

• Easy integration of libraries on
JVM
How to Migrate
Choose a Deploy
Strategy
Archive File
Capistrano
Scheduler
Background Jobs
Clustering

Warbler
✔

Trinidad
✔
✔
✔
✔

TorqueBox
✔
✔
✔
✔
✔
Archive File
Capistrano
Scheduler
Background Jobs
Clustering

Warbler
✔

Trinidad
✔
✔
✔
✔

TorqueBox
✔
✔
✔
✔
✔
JRuby-Lint
https://github.com/jruby/jruby-lint
What We Learned
Gems Alternatives
Wiki: C Extension
Alternatives
https://github.com/jruby/jruby/wiki/C-ExtensionAlternatives
Lock Compatible
Version
gem 'rubyzip', '<1.0.0'
*nix to JVM
•
Cannot trap all signals
•
No Kernel#fork
Kernel#fork → Thread.new
Thread-safety
Avoid Sharing Mutable
State Between Threads
Global Variable
Class Variable
Class Instance Variable
Lazy Initialization →
Preload
class Cvv
✘
def self.redis
@@redis ||= Redis.new(...)
end
end
class Cvv
def self.redis
@@redis
end
def self.redis=(r)
@@redis = r
end
end

✔

!

# config/initializers/cvv.rb
Cvv.redis ...
Thread Local Storage
class Processor
class_attribute :skip

✘

!

def execute
do_something unless self.class.skip
end
end
✔

class Processor
def self.skip
Thread.current['Processor.skip']
end
def self.skip=(s)
Thread.current['Processor.skip'] =...
Atomic Variable
class Airlock
class_variable :enabled
end

✘
# gem 'atomic'!
✔
class Airlock!
@@enabled = Atomic.new(false)!
def self.enabled!
@@enabled.value!
end!
def self.enabled=(...
Locks
require 'thread'!
mutex = Mutex.new!
!

Thread.new do!
mutex.synchronize do!
...!
end!
end
Reference:
Concurrency in JRuby
https://github.com/jruby/jruby/wiki/Concurrency-injruby
Reference: Ruby
Mutithreading
http://www.tutorialspoint.com/ruby/
ruby_multithreading.htm
Resque
•
Jobs run in the same process	

•
Free the resources
•
No Fork
OpenSSL
Full OpenSSL Support
gem 'jruby-openssl'
Different Cryptography
Implementations
https://github.com/jruby/jruby/issues/931
Cryptography Adapter

• Use OpenSSL in CRuby	

• Use JCE directly in JRuby
(java_import)
Tuning
TorqueBox + JBoss
Connection Pool Size
Thread Pool Size
JVM Memory
How To?

• Benchmark	

• Monitoring
References
Deploying with
JRuby
JRuby Wiki
https://github.com/jruby/jruby/wiki
Migrate to JRuby
Migrate to JRuby
Upcoming SlideShare
Loading in …5
×

Migrate to JRuby

490 views
381 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
490
On SlideShare
0
From Embeds
0
Number of Embeds
1
Actions
Shares
0
Downloads
2
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

×