Deploying with JRuby
      with Joe Kutner
HTTP
            Request




          Apache/Nginx




 MRI                      MRI

Mongrel                  Mongrel
Ruby     Ruby     Ruby
Thread   Thread   Thread




          GIL




         Kernel
         Thread
HTTP
          Request




        Apache/Nginx




            JVM




JRuby
                       Thread
MRI
M = N = 16
...
data.size         #=> 256
data.compact.size #=> 256
MRI                        JRuby
M = N = 16                  M = N = 16
...                         ...
data.size         #=> 256   data.size         #=> 244
data.compact.size #=> 256   data.compact.size #=> 229
MRI

15.616822
15.675064
MRI         JRuby

15.616822    7.770000
15.675064    4.245000
Deployment
People
Processes
        Technologies
Archive File

  Capistrano

Background Jobs

   Clustering

     PaaS
Warbler         Trinidad         TorqueBox
Archive File                       Archive File

                 Capistrano         Capistrano

               Background Jobs   Background Jobs

                                    Clustering

   PaaS             PaaS
Warbler


$ warble war
Warbler

                     Tomcat/Jetty
                        Server

WAR
       SSH/FTP/SMB
File
Trinidad

$ rails s trinidad

         or


$ rackup -s trinidad
Trinidad

                             Trinidad
app1/
                                  Extensions
|-- app/
|-- config/
|-- db/         Capistrano
                                    Job Scheduler
|-- lib/
`-- config.ru                          (Quartz)


                                   Background Jobs
                                       (Resque)
app2/
|-- app/
|-- config/
|-- db/         Capistrano             DB Pool
|-- lib/                           (Commons DBCP)
`-- config.ru
TorqueBox

 $ torquebox run

       then


$ torquebox deploy
TorqueBox

                              TorqueBox
                                      Job Scheduler
app1/
|-- app/
|-- config/
|-- db/          Capistrano             Messaging
|-- lib/
`-- config.ru
                                    Session Replication


                                     High Availability

   Knob
                SSH/FTP/SMB
    File                                 Services


                                        Stomplets


                                        Clustering
TorqueBox Cluster

             TorqueBox



 TorqueBox               TorqueBox




 TorqueBox               TorqueBox



             TorqueBox
Alternatives


Google AppEngine

Kirk

Mizuno
Which Strategy is right
       for me?

 People

 Process

 Technology

Deploying with JRuby

  • 1.
    Deploying with JRuby with Joe Kutner
  • 2.
    HTTP Request Apache/Nginx MRI MRI Mongrel Mongrel
  • 3.
    Ruby Ruby Ruby Thread Thread Thread GIL Kernel Thread
  • 4.
    HTTP Request Apache/Nginx JVM JRuby Thread
  • 6.
    MRI M = N= 16 ... data.size #=> 256 data.compact.size #=> 256
  • 7.
    MRI JRuby M = N = 16 M = N = 16 ... ... data.size #=> 256 data.size #=> 244 data.compact.size #=> 256 data.compact.size #=> 229
  • 9.
  • 10.
    MRI JRuby 15.616822 7.770000 15.675064 4.245000
  • 11.
  • 12.
    People Processes Technologies
  • 13.
    Archive File Capistrano Background Jobs Clustering PaaS
  • 14.
    Warbler Trinidad TorqueBox Archive File Archive File Capistrano Capistrano Background Jobs Background Jobs Clustering PaaS PaaS
  • 15.
  • 16.
    Warbler Tomcat/Jetty Server WAR SSH/FTP/SMB File
  • 17.
    Trinidad $ rails strinidad or $ rackup -s trinidad
  • 18.
    Trinidad Trinidad app1/ Extensions |-- app/ |-- config/ |-- db/ Capistrano Job Scheduler |-- lib/ `-- config.ru (Quartz) Background Jobs (Resque) app2/ |-- app/ |-- config/ |-- db/ Capistrano DB Pool |-- lib/ (Commons DBCP) `-- config.ru
  • 19.
    TorqueBox $ torqueboxrun then $ torquebox deploy
  • 20.
    TorqueBox TorqueBox Job Scheduler app1/ |-- app/ |-- config/ |-- db/ Capistrano Messaging |-- lib/ `-- config.ru Session Replication High Availability Knob SSH/FTP/SMB File Services Stomplets Clustering
  • 21.
    TorqueBox Cluster TorqueBox TorqueBox TorqueBox TorqueBox TorqueBox TorqueBox
  • 22.
  • 23.
    Which Strategy isright for me? People Process Technology

Editor's Notes

  • #2 I’m a programmer, but I don’t tell that to my family. I tell them I’m a “Software Architect” because it doesn’t disappoint them as much. \n\nWhat we do is really about solving problems. In fact, I think easiest part of our job is writing the code. Figuring out how to tackle a problem is much harder. Sometimes we need to punch out some code to get through a problem -- it helps us realize what we are doing. But there are lots of different ways to solve problems:\n\nDivide and conquer: break in down into more manageable parts.\nTrial and Error: see what sticks to the wall.\nRoot Cause Analysis: eliminating the cause of the problem.\n\nWhen it comes to Ruby applications, JRuby is a means of eliminating the root cause of many architectural and deployment problems.\n\nBut I don’t like the phrase “root cause analysis” -- it’s too stuffy. I prefer the analogy to “changing the conversation.” Who watches Mad Men?\n\nIf you don’t like what’s being said, change the conversation\nIf you don’t like the solutions, change the problem.\n\nHave you ever focused really hard on a difficult problem, then realized (probably in the shower) that you could solve the problem by avoiding it altogether?\nOf course you have.\nIf you don’t like what’s being said, change the conversation\nIf you don’t like the solutions, change the problem.\nThat’s what this talk is about. There are problems with deploying MRI-based web applications that i’ll describe in a moment. \n\n
  • #3 Memory Growth (each process has a copy of the app in memory)\nDatabase Pools (each process has it’s own DB pool)\nSlow Restarts\nZombies.\n\nThe result of these problems has been the additional layers. Unicorn and Passenger try to solve these problems. pgpool on the backend. God and Monit. \n\nBut really, we need to change the conversation. We need to eliminate the root cause.\n\nIt’s all because of the GIL\n\n\n\n
  • #4 It’s all because of the GIL\nMultiple Ruby threads to one OS thread.\nYea, garbage collection and IO can happen concurrently, but not our code.\nThis is to protect the programmer.\n\nJVM does not have a GIL \nIt maps User threads directly to OS threads.\n\nA lot of folks want to remove the GIL -- to make MRI more like the JVM. It ain’t gonna happen.\nAt RubyConf 2011 someone asked Matz if the GIL would be remove. He said no. He doesn’t want MRI to be “that kind of platform.” \n\nI’m with Matz on this one. Ruby is supposed to make it easy for the program - Matz doesn’t care if it’s fast.\nThere are tons of applications where having a GIL doesn’t matter. \nBut web apps are not one of them.\n\n
  • #5 one process. no balancing layers. no peripheral background processes. no external db pool (unless you’re running a cluster that shares a db instead of using replication).\n
  • #6 Interesting question: is this thread-safe on MRI?\n\nIt depends. Do you care about the order of the data array?\n
  • #7 Interesting question: is this thread-safe on MRI?\n\nIt depends. Do you care about the order of the data array?\n
  • #8 This program runs the same benchmark twice. In each run it calculates the factorial of 99 400,000 times. \nThe first time, it uses a single thread. The second time, it uses four threads. \n\nInteresting question: is this thread-safe on MRI?\n\nIt depends. Do you care about the order of the data array?\n
  • #9 This program runs the same benchmark twice. In each run it calculates the factorial of 99 400,000 times. \nThe first time, it uses a single thread. The second time, it uses four threads. \n\nInteresting question: is this thread-safe on MRI?\n\nIt depends. Do you care about the order of the data array?\n
  • #10 That’s how JRuby changes the conversation for our architectural problems. But how do we implement this?\nThat’s where deployment comes in.\nDeployment is the process of taking something we’ve built, and delivering it to the customer. That includes the application and the platform it runs. So we have two considerations:\n1. how do we deploy our code\n2. how do we deploy our infrastructure.\nTraditional Ruby deployment takes a directory of loose files and launches them in a sort of shotgun blast arcoss a network, and we just have to hope that everything arrived intact. \nBut JRuby allows us to package our application -- independently of the platform it runs on -- and distribute it as a single file. This means we can encrypt it, sign it, or even compile it.\n
  • #11 \n
  • #12 \n
  • #13 \n
  • #14 Archive File / Capistrano\nBackground Jobs\nClustering\nPaaS\n\n
  • #15 \n
  • #16 \n
  • #17 \n
  • #18 \n
  • #19 \n
  • #20 \n
  • #21 \n
  • #22 You can still deploy your JRuby applications with Capistrano if you want, and there may be good reasons for do so. But that’s just it -- you have to figure out the nature of your constraints and select the best deployment strategy to suit that world.\n