TorqueBox at DC:JBUG - November 2011
Upcoming SlideShare
Loading in...5

TorqueBox at DC:JBUG - November 2011



Presentation about TorqueBox to the DC:JBUG in November, 2011.

Presentation about TorqueBox to the DC:JBUG in November, 2011.



Total Views
Views on SlideShare
Embed Views



8 Embeds 1,249 888 266 47
http://localhost 19 17 6 4 2



Upload Details

Uploaded via as Adobe PDF

Usage Rights

CC Attribution-ShareAlike LicenseCC Attribution-ShareAlike License

Report content

Flagged as inappropriate Flag as inappropriate
Flag as inappropriate

Select your reason for flagging this presentation as inappropriate.

  • Full Name Full Name Comment goes here.
    Are you sure you want to
    Your message goes here
Post Comment
Edit your comment

TorqueBox at DC:JBUG - November 2011 TorqueBox at DC:JBUG - November 2011 Presentation Transcript

  • TorqueBoxThe  expressiveness  of  Ruby The  power  of  Java Bob  McWhirter JBoss  Fellow
  • Bob  McWhirter‣ JBoss  Fellow  at  Red  Hat‣ Founder  of... ‣ The  Codehaus ‣ Drools ‣ TorqueBox ‣ DeltaCloud  API
  • but  it’s  a  team
  • What  is  TorqueBox?TorqueBox  glues  JRuby  to  the  JBoss  Java  Application  Server  (JBoss  AS).
  • Why  JRuby‣ Real  threads‣ Many  garbage-­collection  options‣ Lots  of  JVM  research‣ Integration  with  Java‣ Fast!
  • What  is  JBoss  AS?JBoss  AS  is  full  JavaEE  application  server,  providing  web,  caching,  messaging,  clustering,  failover,  etc.
  • Ruby!APIs!/!Programming!Models Java!APIs!/!Programming!Models Message Processors Polyglot WebSockets InjectionSinatra Rails Jobs STOMP POJO REST Servlet Rack Daemons Tasks Spring JMS JavaEE JRuby!Component!Deployers!&!Gems Java!Enterprise!Services JBoss Web Messaging Infinispan Cache TorqueBox HornetQ Transactions Core Quartz Security TorqueBox Core PicketLink JRuby with JIT Managed Services Container Java Virtual Machine
  • But  Java  is  enterprisey,  while  Ruby  is  agile...!
  • “Java  is  a  DSL  for  taking  large  XML  files  and  converting  them  to  stack  traces” Scott  Bellware
  • One  of  our  mantras:XML  means  we’ve  <failed/>
  • First  Order  GoalsBe  a  great  traditional  Ruby  environment ‣ Rack ‣ Rails ‣ Sinatra ‣ Padrino
  • Second  Order  GoalsBe  better  than  a  traditional  environment: ‣ Services ‣ Caching ‣ Jobs ‣ WebSockets ‣ Messaging ‣ HA/Failover ‣ Transactions
  • First:  web
  • Your  appmyapp/    config/        application.rb        database.yml        torquebox.yml    app/        views/        controllers/        models/
  • 1  AS,  many  apps config/torquebox.ymlapplication:    root:  /path/to/myappweb:    context:  /    host:  www.myapp.comenvironment:    RAILS_ENV:  production    MAIL_HOST:
  • Compare  to... WEB-­INF/web.xml<?xml  version="1.0"  encoding="UTF-­8"?><web-­app  version="2.5"          xmlns=""        xmlns:xsi="­instance"        xsi:schemaLocation="­app_2_5.xsd">  <context-­param>      <param-­name></param-­name>      <param-­value></param-­value>  </context-­param>  <servlet>      <display-­name>Servlet1</display-­name>      <servlet-­name>Servlet1</servlet-­name>      <servlet-­class>test.Servlet1</servlet-­class>  </servlet>  <servlet-­mapping>      <servlet-­name>Servlet1</servlet-­name>      <url-­pattern>/Servlet1</url-­pattern>  </servlet-­mapping>  <welcome-­file-­list>      <welcome-­file>index.html</welcome-­file>  </welcome-­file-­list></web-­app>
  • Make  Love,  not  WARLive,  where  it  sits  on  disk. No  archive  required.
  • (caveat)Requires  runtime  reloading  support  in  your  framework,  but  not  redeployment. Rails                Rack::Reloader
  • Works  as  expected,almost  boring
  • Second  order  goal:services
  • Daemons!start() ...time  passes... stop()
  • Example  service app/services/my_service.rbclass  MyServer    def  initialize(opts)    end    def  start    end    def  stop    endend
  • Service  config config/torquebox.ymlservices:    MyService:        some_key:  some_value    MyCriticalService:        singleton:  true
  • singleton? true Ensures  one  (and  only  one)  instance  is  running  within  the  cluster  at  a  time,  with  failover.
  • singleton? false (default)
  • Second  order  goal:scheduled  jobs
  • cron-­like-­ every  3  hours...-­ the  first  of  each  month...-­ on  Tuesdays...-­ when  the  world  ends...
  • Job  example apps/jobs/my_job.rbclass  MyJob        def  run()        #  your  code  here    endend
  • Job  config config/torquebox.ymljobs:    monthly_reminder:        description:  sends  reminders        job:  MyJob        cron:  ‘0  0  0  1  *  ?’        singleton:  true    file_cleaner:        description:  clean  files  on  node        job:  FileCleaner        cron:  ‘5  *  *  *  *  ?’
  • Second  order  goal:messaging messaging messaging (we  really  like  messaging)
  • Darn  zippy  JMS  broker
  • Where  to,  my  friend? config/torquebox.ymlqueues:    /queues/puppies:    /queues/kittens:        durable:  falsetopics:    /topics/memes:
  • Consumer Consumer Consumer Consumer Topic Queue
  • Let’s  go! arbitrary_app_stuff.rbclass  MyController  <  ApplicationController    include  TorqueBox::Injectors      def  index        @queue  =  inject(  ‘/queues/puppies’  )        @queue.publish(  “Oh,  puppies!”  )    endend
  • Now  arriving... app/processors/my_processorinclude  TorqueBox::Messagingclass  MyProcessor  <  MessageProcessor    def  initialize(opts)    end    def  on_message(body)        #  your  code  here.    endend
  • Processor  config config/torquebox.ymlmessaging:    /queues/puppies:        MyHandler:            concurrency:  5            config:                some_key:  some_value    /queues/kittens:        MyOtherHandler:            singleton:  true
  • But  that’s  not  all!
  • What  makes  messaging  special?
  • Async
  • BackgroundablesGo  asynchronous  without  having  to  think  about  messaging.
  • Enabling my_arbitrary_file.rbclass  User    include  TorqueBox::Messaging::Backgroundable    def  do_something_slowly()        upload_over_300baud_modem()    endend
  • What?Teaches  your  class  how  to  invoke  methods  across  an  implicit  queue. Yay  mix-­ins!
  • Using  explicitly my_other_arbitrary_file.rbu  =  User.newu.do_something_slowly()u.background.do_something_slowly()
  • Forcing my_arbitrary_file.rbclass  User    include  TorqueBox::Messaging::Backgroundable    always_background  :do_something_slowly    def  do_something_slowly()        upload_over_300baud_modem()    endend
  • Using  implicitly my_other_arbitrary_file.rbu  =  User.newu.do_something_slowly()
  • The  FUTURE!future  =  user.do_something_slowly()future.started?future.complete?future.error?future.result
  • Progress!class  User    include  TorqueBox::Backgroundable    always_background  :do_something_slowly    def  do_something_slowly        upload_over_modem()        future.status  =  “uploaded”        alert_authorities        future.status  =  “alerted”    endend
  • Queryfuture  =  user.do_something_slowly()future.status_changed?future.status  #  =>  “uploaded”
  • Second  order  goal:transactions
  • TransactionsQueue Database Infinispan Your!Code Topic
  • [ ] Transactions Queue Database Infinispan Your!Code TopicXA  distributed,  multi-­resource  transaction
  • XA Everything  succeeds  or  everything  fails‣ HornetQ  supports  XA‣ Infinispan  supports  XA‣ TorqueBox  makes  ActiveRecord   support  XA,  if  your  database  does.
  • Second  order  goal:caching and  more
  • InfinispanNode Node Node NodeItem #1 Item #1 Item #2 Item #3Item #4 Item #2 Item #3 Item #4 Replicated  &  Distributed
  • Replace   memcachedPlaces  Rails  can  use  memcached?Now  you’re  using  Infinispan.
  • As  an  object-­storeUsable  behind  DataMapper  through  dm-­infinispan-­adapter.
  • Directly my_arbitrary_file.rbmy_cache  =                          :name=>‘my-­cache’,                          :mode=>:replicated                      )my_cache.put(...)my_cache.get(...)
  • Clustered  web  sessions...
  • Second  order  goal:websockets
  • to  the  browserStream-­Oriented  Message  Protocol (I  did  say  we  really  really  liked  messaging)
  • Bare  WebSockets  and  clusters  don’t  get  along.
  • WebSockets  is  already  frame-­based,  not  streaming... Use  messaging!
  • But  directly  exposing  your  JMS  to  the  internet  seems  unwise...­r-­brown/4686613540/
  • Stomplets  act  as  a  controller  between  user  and  JMS.
  • Browser Stomplet JMS!Stuff
  • Example  Stomplet app/stomplets/my_stomplet.rbclass  MyStomplet    def  on_subscribe(subscriber)    end    def  on_unsubscribe(subscriber)    end    def  on_message(stomp_message,  session)    endend
  • Configuration config/torquebox.ymlstomp:    stomplets:        animals:            route:  ‘/animals/:type’            class:  MyStomplet
  • JMS  helperssubscribe_to(  subscriber,  jms_dest  )send_to(  jms_dest,  message,  headers={}  )
  • Second  order  goal:injection
  • Resource  Injection‣ Inversion  of  control‣ Allows  for  easier  testing‣ Inject  non-­Ruby  things
  • Injectables‣ Services‣ Queues  &  Topics‣ Java  CDI  components
  • Destinationsinject(  ‘/queues/kittens’  ).publish(...)inject(  ‘/topics/puppies’  ).publish(...)
  • CDI MyJavaThing.javapackage  com.mycorp;;@ApplicationScopedpublic  class  MyJavaThing  {    public  void  frob()  {  ...}}
  • CDI my_arbitrary_file.rbinject(  com.mycorp.MyJavaThing  ).frob()
  • Clustering
  • There  is  no  cluster  (noun),but  things  can  cluster  (verb).
  • Clusterstuff‣ Web  sessions‣ Web  load-­balancing‣ Caches‣ Messaging  destinations‣ HA  coordination
  • JGroupsMany  discovery  and  communication  options.‣ Multicast‣ Rendezvous‣ S3  except   eat: (Cav netQ)‣ File Hor
  • mod_cluster httpd!+!mod_clusterAS AS AS
  • performance
  • Throughput1208040 0 40min TorqueBox Unicorn Passenger Higher  is  better Trinidad
  • Latency 65s 16s 4s 1s256ms64ms 40min TorqueBox Unicorn Passenger Lower  is  better Trinidad
  • CPU  Usage80604020 0 40min TorqueBox Unicorn Passenger Lower  is  better Trinidad
  • Free  Memory7gb6gb5gb4gb3gb2gb1gb 0 40min TorqueBox Unicorn Passenger Higher  is  better Trinidad
  • Management
  • Managing  groups  of  servers  is  orthogonal  to  the  clustering  of  servers.
  • API Domain!Controller API API Host!Controller Host!ControllerAPI APIAS AS AS AS AS AS
  • Ecosystem
  • BackstageDashboard  to  monitor  and  control  Ruby  components.With  a  RESTful  API.
  • StompBoxGit-­based  application  deployment  straight  to  your  server.
  • TorqueSpecRSpec  enhancements  for  integration  testing.Start  TorqueBox  &  deploy  apps  are  part  of  your  specs.In-­container  testing,  too!
  • Cloudrific!
  • ‣ Ruby‣ Java‣ PHP‣ Python‣ Perl
  • ‣ Multi-­tenant  machines‣ High  density  (let  OS  swap)‣ Git-­based  deployment‣ Constrained  to  achieve  density‣ SELinux  to  secure  tenants
  • Resources‣‣‣ #torquebox  on  Freenode‣ @torquebox  on  Twitter‣ The  tall  guy  up  front
  • Hey,  thanks  for  having  me!