Your SlideShare is downloading. ×
0
Scaling Rails Applications     with TorqueBox         Ben Browning
Ben Browning•TorqueBox Contributor•Red Hat Senior Engineer since July 2010•Ruby yay! JVM yay! Java boo! JRuby yay!
The Team
TorqueBox•The power of JBoss with the expressiveness of Ruby•Rails, Sinatra, Rack and non-web applications running on top ...
Rails“Ruby on Rails® is an open-source web frameworkthat’s optimized for programmer happiness andsustainable productivity....
ScalingAbility to increase throughput by adding hardware
Learn By (Beer) ExampleLet’s create an application to find the most popular beeraccording to Twitter.
Beer Tweets•Web front-end•Twitter Streaming API client•Scheduled job to clean old beer tweets•Caching so our database does...
Web Front-endclass BeersController < ApplicationController def most_popular  @popular_beers = Beer.most_popular(:limit => ...
Twitter Streaming API Client•Connect to Twitter’s streaming API and find all tweets containing “beer”•Needs to run as a dae...
TorqueBox Services•Long-running, non-web daemons that share the runtime environment and deployment lifecycle of your app•A...
Twitter Streaming API Clientclass BeerService def initialize(options)  @client = StreamingTwitter.new(options["username"],...
Twitter Streaming API Clientclass BeerService def find_beer  @client.search(beer) do |tweet|   Beer.create_from_json(tweet)...
Twitter Streaming API Clientconfig/torquebox.yml:services: beer_service:  username: ilikebeer  password: sodoyou
Clean Stale Beer•Delete all beer-related tweets older than 7 days•Run once an hour to prune in manageable chunks
Scheduled Jobs•Tasks that need to be executed on a recurring schedule•A class with a run() method
Clean Stale Beerclass BeerCleaner def run()  Beer.clean_older_than(7.days) endend
Clean Stale Beerconfig/torquebox.yml:jobs:  beer_cleaner:   description: Clean stale beer-related tweets   job: BeerCleaner...
CachingWe’re showing the same list of most popular beers to allusers so why hit the database on every request?
Caching Web Front-endclass BeersController < ApplicationController caches_action :most_popular, :expires_in => 30.seconds ...
Beer TweetsWe’re collecting tweets about beer, serving the resultsup via a cached web interface, and keeping ourdatabase c...
We’re Done, Right?We’ve added all our features and deployed onTorqueBox so we can handle limitless load, right?
Benchmarks
Benchmarks
We’re Done, Right?No way - it’s beer and Twitter! This will be wildlypopular with social alcoholics and we need to planacc...
Performance != ScalabilityJust because an application performs well on a singleserver doesn’t mean it can scale.
Add More ServersWell, before we can do that we need a load balancer toroute requests to multiple servers.
mod_clusterThe same mod_cluster you know and love to use withJBoss AS works with TorqueBox.
mod_clusterBased on Apache’s mod_proxy but with two-waycommunication to JBoss and TorqueBox providingintelligent request r...
mod_cluster
Add More ServersAs each TorqueBox instance boots it will find the otherTorqueBox and mod_cluster instances and add itself t...
Sessions•By default Rails stores all session data in cookies•Production Rails applications usually use a database or memca...
TorqueBox Sessionsconfig/initializers/session_store.rb:BeerTweets::Application.config. session_store TorqueBox::Session::Ser...
TorqueBox Sessions•Server-side sessions without hitting the database or requiring an external process (memcached)•Uses JBo...
Are We Scaled Yet?We’ve taken care of the load balancer and sessionreplication, but what about our Twitter Streaming APIcl...
Twitter Streaming API Client•By default our service will start on every node in the cluster•Sometimes that’s what you want...
HASingleton Services•TorqueBox supports highly-available singleton services•The service will only run on one node in the c...
HASingleton Servicesconfig/torquebox.yml:services: beer_service:  username: ilikebeer  password: sodoyou  singleton: true
Twitter Streaming API Client•Now our service will only run on one node, but what happens if tweets come in from Twitter fa...
Backgroundable•Convert any method call into an asynchronous call•Uses HornetQ under the hood and calls are load- balanced ...
Backgroundableclass BeerService def find_beer  @client.search(beer) do |tweet|   Beer.background.create_from_json(tweet)  e...
Asynchronous Tasksclass BeerTask < TorqueBox::Messaging::Task def create_from_json(payload)  Beer.create_from_json(payload...
Asynchronous Tasksclass BeerService def find_beer  @client.search(beer) do |tweet|   BeerTask.async(:create_from_json, :twe...
Twitter Streaming API ClientAll nodes in our cluster will now process incomingtweets even though only a single node mainta...
Now We’re Scaled, Right?Not quite - we still have that pesky job that cleans stalebeer to deal with.
Clean Stale Beer•By default, scheduled jobs will run on all nodes in a cluster.•We only want our beer cleaning job to run ...
HASingleton Jobsconfig/torquebox.yml:jobs:  beer_cleaner:   description: Clean stale beer-related tweets   job: BeerCleaner...
All Scaled?Almost! We still need to take care of our caching.
Caching•Rails ships with support for multiple cache stores (file- based, in-memory, memcached)•None allow multiple nodes to...
TorqueBoxStore•Rails 3 ActiveSupport::Cache::Store implementation backed by Infinispan•Supports invalidated, replicated, an...
TorqueBoxStoremodule BeerTweets class Application < Rails::Application  config.cache_store :torque_box_store(:mode => :dist...
Are We Scaled?As we add additional nodes to the cluster they increaseour web request throughput, background jobthroughput,...
But Wait, There’s More!
InjectionInject CDI resources, messaging destinations, JNDIentries, MBeans into your Ruby application@questions = inject(‘...
Message Processorsclass SeniorHandler < TorqueBox::Messaging::MessageProcessor def on_message(body)  puts “Processing #{bo...
Message Processorsconfig/torquebox.yml:messaging: /queues/people:  SeniorHandler:   filter: “age >= 55”   concurrency: 2
Queues and Topicsquestions = inject(‘/queues/questions’)answers = inject(‘/queues/answers’)Thread.new do questions.publish...
Queues and Topicsconfig/torquebox.yml:queues: /queues/questions: /queues/answers:
BackStageDashboard and RESTful API to inspect and control Rubycomponents
BackStage
StompBoxEasy Heroku-esque git-based deployments
StompBox
Roadmap1.0.0 Just Released!Upcoming:AS7TransactionsSSODrools / jBPMMobicentsWebSockets
Resources•http://torquebox.org•https://github.com/torquebox•#torquebox on FreeNode•@torquebox
Thanks!
Questions?
Scaling Rails With Torquebox Presented at JUDCon:2011 Boston
Upcoming SlideShare
Loading in...5
×

Scaling Rails With Torquebox Presented at JUDCon:2011 Boston

4,578

Published on

Published in: Technology
1 Comment
5 Likes
Statistics
Notes
  • Must read for Ruby users who can understand it...
       Reply 
    Are you sure you want to  Yes  No
    Your message goes here
No Downloads
Views
Total Views
4,578
On Slideshare
0
From Embeds
0
Number of Embeds
3
Actions
Shares
0
Downloads
64
Comments
1
Likes
5
Embeds 0
No embeds

No notes for slide
  • \n
  • \n
  • \n
  • \n
  • \n
  • myths &amp;#x201C;Ruby doesn&amp;#x2019;t scale, Rails doesn&amp;#x2019;t scale&amp;#x201D;\n
  • scaling out vs scaling up\n
  • \n
  • \n
  • simple Rails controller w/ an accompanying view (not shown) to render the HTML\n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • normal load balancers just forward requests to the backend server\nwith mod_cluster, TorqueBox and JBoss AS can send load and other information to the load balancer\n
  • \n
  • When using multicast discovery - there are some other tricks for networks that don&amp;#x2019;t support multicast\n
  • \n
  • \n
  • Java and Rails applications can share session data\nAS session replication is battle-proven, very configurable\n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • If backgroundable is too magic for you, we also support explicit asynchronous tasks\n
  • \n
  • \n
  • \n
  • \n
  • Just like HASingleton services\n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • Transcript of "Scaling Rails With Torquebox Presented at JUDCon:2011 Boston"

    1. 1. Scaling Rails Applications with TorqueBox Ben Browning
    2. 2. Ben Browning•TorqueBox Contributor•Red Hat Senior Engineer since July 2010•Ruby yay! JVM yay! Java boo! JRuby yay!
    3. 3. The Team
    4. 4. TorqueBox•The power of JBoss with the expressiveness of Ruby•Rails, Sinatra, Rack and non-web applications running on top of JBoss AS and JRuby•Messaging, Asynchronous Tasks, Scheduled Jobs, and Services built-in
    5. 5. Rails“Ruby on Rails® is an open-source web frameworkthat’s optimized for programmer happiness andsustainable productivity. It lets you write beautiful codeby favoring convention over configuration.” - http://rubyonrails.org
    6. 6. ScalingAbility to increase throughput by adding hardware
    7. 7. Learn By (Beer) ExampleLet’s create an application to find the most popular beeraccording to Twitter.
    8. 8. Beer Tweets•Web front-end•Twitter Streaming API client•Scheduled job to clean old beer tweets•Caching so our database doesn’t fall over
    9. 9. Web Front-endclass BeersController < ApplicationController def most_popular @popular_beers = Beer.most_popular(:limit => 25) endend
    10. 10. Twitter Streaming API Client•Connect to Twitter’s streaming API and find all tweets containing “beer”•Needs to run as a daemon, outside of the web request / response cycle
    11. 11. TorqueBox Services•Long-running, non-web daemons that share the runtime environment and deployment lifecycle of your app•A class with initialize( Hash ), start(), and stop() methods
    12. 12. Twitter Streaming API Clientclass BeerService def initialize(options) @client = StreamingTwitter.new(options["username"], options["password"]) end def start Thread.new { find_beer } end def stop @client.disconnect endend
    13. 13. Twitter Streaming API Clientclass BeerService def find_beer @client.search(beer) do |tweet| Beer.create_from_json(tweet) end endend
    14. 14. Twitter Streaming API Clientconfig/torquebox.yml:services: beer_service: username: ilikebeer password: sodoyou
    15. 15. Clean Stale Beer•Delete all beer-related tweets older than 7 days•Run once an hour to prune in manageable chunks
    16. 16. Scheduled Jobs•Tasks that need to be executed on a recurring schedule•A class with a run() method
    17. 17. Clean Stale Beerclass BeerCleaner def run() Beer.clean_older_than(7.days) endend
    18. 18. Clean Stale Beerconfig/torquebox.yml:jobs: beer_cleaner: description: Clean stale beer-related tweets job: BeerCleaner cron: 0 44 * * * ?
    19. 19. CachingWe’re showing the same list of most popular beers to allusers so why hit the database on every request?
    20. 20. Caching Web Front-endclass BeersController < ApplicationController caches_action :most_popular, :expires_in => 30.seconds def most_popular @popular_beers = Beer.most_popular(:limit => 25) endend
    21. 21. Beer TweetsWe’re collecting tweets about beer, serving the resultsup via a cached web interface, and keeping ourdatabase cleaned of stale data.
    22. 22. We’re Done, Right?We’ve added all our features and deployed onTorqueBox so we can handle limitless load, right?
    23. 23. Benchmarks
    24. 24. Benchmarks
    25. 25. We’re Done, Right?No way - it’s beer and Twitter! This will be wildlypopular with social alcoholics and we need to planaccordingly - we need to scale!
    26. 26. Performance != ScalabilityJust because an application performs well on a singleserver doesn’t mean it can scale.
    27. 27. Add More ServersWell, before we can do that we need a load balancer toroute requests to multiple servers.
    28. 28. mod_clusterThe same mod_cluster you know and love to use withJBoss AS works with TorqueBox.
    29. 29. mod_clusterBased on Apache’s mod_proxy but with two-waycommunication to JBoss and TorqueBox providingintelligent request routing based on load.
    30. 30. mod_cluster
    31. 31. Add More ServersAs each TorqueBox instance boots it will find the otherTorqueBox and mod_cluster instances and add itself tothe cluster.
    32. 32. Sessions•By default Rails stores all session data in cookies•Production Rails applications usually use a database or memcached for session storage•TorqueBox provides its own session storage
    33. 33. TorqueBox Sessionsconfig/initializers/session_store.rb:BeerTweets::Application.config. session_store TorqueBox::Session::ServletStore
    34. 34. TorqueBox Sessions•Server-side sessions without hitting the database or requiring an external process (memcached)•Uses JBoss AS session replication under the hood
    35. 35. Are We Scaled Yet?We’ve taken care of the load balancer and sessionreplication, but what about our Twitter Streaming APIclient? How will it scale?
    36. 36. Twitter Streaming API Client•By default our service will start on every node in the cluster•Sometimes that’s what you want, but not in this case; we only want one copy of each beer tweet to be saved.
    37. 37. HASingleton Services•TorqueBox supports highly-available singleton services•The service will only run on one node in the cluster•If that node goes down, another node will start the service
    38. 38. HASingleton Servicesconfig/torquebox.yml:services: beer_service: username: ilikebeer password: sodoyou singleton: true
    39. 39. Twitter Streaming API Client•Now our service will only run on one node, but what happens if tweets come in from Twitter faster than that one node can process them?
    40. 40. Backgroundable•Convert any method call into an asynchronous call•Uses HornetQ under the hood and calls are load- balanced across the cluster
    41. 41. Backgroundableclass BeerService def find_beer @client.search(beer) do |tweet| Beer.background.create_from_json(tweet) end endend
    42. 42. Asynchronous Tasksclass BeerTask < TorqueBox::Messaging::Task def create_from_json(payload) Beer.create_from_json(payload[:tweet]) endend
    43. 43. Asynchronous Tasksclass BeerService def find_beer @client.search(beer) do |tweet| BeerTask.async(:create_from_json, :tweet => tweet) end endend
    44. 44. Twitter Streaming API ClientAll nodes in our cluster will now process incomingtweets even though only a single node maintains a httpconnection to Twitter.
    45. 45. Now We’re Scaled, Right?Not quite - we still have that pesky job that cleans stalebeer to deal with.
    46. 46. Clean Stale Beer•By default, scheduled jobs will run on all nodes in a cluster.•We only want our beer cleaning job to run on a single node.
    47. 47. HASingleton Jobsconfig/torquebox.yml:jobs: beer_cleaner: description: Clean stale beer-related tweets job: BeerCleaner cron: 0 44 * * * ? singleton: true
    48. 48. All Scaled?Almost! We still need to take care of our caching.
    49. 49. Caching•Rails ships with support for multiple cache stores (file- based, in-memory, memcached)•None allow multiple nodes to share a common cache without setting up an external process
    50. 50. TorqueBoxStore•Rails 3 ActiveSupport::Cache::Store implementation backed by Infinispan•Supports invalidated, replicated, and distributed clustering modes
    51. 51. TorqueBoxStoremodule BeerTweets class Application < Rails::Application config.cache_store :torque_box_store(:mode => :distributed, :sync => false) endend
    52. 52. Are We Scaled?As we add additional nodes to the cluster they increaseour web request throughput, background jobthroughput, and cache capacity. We’re scaled!
    53. 53. But Wait, There’s More!
    54. 54. InjectionInject CDI resources, messaging destinations, JNDIentries, MBeans into your Ruby application@questions = inject(‘/queues/questions’)@datasource = inject(‘java:comp/env/jdbc/myDS’)@thing = inject(com.mycorp.Something)@bean = inject(‘SomeMCBean’)
    55. 55. Message Processorsclass SeniorHandler < TorqueBox::Messaging::MessageProcessor def on_message(body) puts “Processing #{body} of #{message}” endend
    56. 56. Message Processorsconfig/torquebox.yml:messaging: /queues/people: SeniorHandler: filter: “age >= 55” concurrency: 2
    57. 57. Queues and Topicsquestions = inject(‘/queues/questions’)answers = inject(‘/queues/answers’)Thread.new do questions.publish ‘What time is it?’ puts answers.receive(:timeout => 1000)endputs questions.receiveanswers.publish Time.now
    58. 58. Queues and Topicsconfig/torquebox.yml:queues: /queues/questions: /queues/answers:
    59. 59. BackStageDashboard and RESTful API to inspect and control Rubycomponents
    60. 60. BackStage
    61. 61. StompBoxEasy Heroku-esque git-based deployments
    62. 62. StompBox
    63. 63. Roadmap1.0.0 Just Released!Upcoming:AS7TransactionsSSODrools / jBPMMobicentsWebSockets
    64. 64. Resources•http://torquebox.org•https://github.com/torquebox•#torquebox on FreeNode•@torquebox
    65. 65. Thanks!
    66. 66. Questions?
    1. A particular slide catching your eye?

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

    ×