0
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

273

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
273
On Slideshare
0
From Embeds
0
Number of Embeds
0
Actions
Shares
0
Downloads
2
Comments
0
Likes
0
Embeds 0
No embeds

No notes for slide

Transcript of "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
  1. A particular slide catching your eye?

    Clipping is a handy way to collect important slides you want to go back to later.

×