Dropping Rails for Dropwizard? (from Abril Pro Ruby 2014)

Dropping Rails for Dropwizard? (from Abril Pro Ruby 2014)

Due to the success of Rails, many successful organizations find themselves with a Rails application that needs partitioning. Many organizations have chosen to largely abandon Ruby during this transition, yet the reasoning is often reactionary. This talk explores the approach Yammer has taken, comparing Rails and the Java-based Dropwizard framework. Both have the mantra of getting decision-making and repetition out of the way so you can get things done. Dropwizard takes a slightly different approach by putting emphasis on "production-ready out-of-the-box." In this talk, attendees will gain insights into the options Rubyists have for replicating Dropwizard's ops-focus in Rails. Attendees will also come away with an understanding of why Dropwizard's focus on operations and metrics makes it appealing to organizations tearing apart their monolithic Rails application. By assembling similar toolsets for Ruby and Java services, we'll be better positioned to choose between them on the merits of the stack and language.

Af20dc6a55a70b601c632c064afedac1?s=128

Brian Morton

April 26, 2014
Tweet

Transcript

  1. None
  2. None
  3. Freemium enterprise social network Acquired by Microsoft in 2012 Evolved

    into a service oriented architecture
  4. None
  5. We didn’t drop Rails.

  6. None
  7. None
  8. None
  9. None
  10. None
  11. None
  12. None
  13. Look at how another framework solves problems Choose the right

    stack to build on Apply the good parts back to our Ruby/Rails apps
  14. Look at how another framework solves problems Choose the right

    stack to build on Apply the good parts back to our Ruby/Rails apps
  15. None
  16. None
  17. None
  18. None
  19. None
  20. $  java  -­‐jar  target/dropwizard-­‐demo.jar  server  sample.yml   INFO    [2014-­‐04-­‐25

     15:11:30,057]  io.dropwizard.server.ServerFactory:  Starting   SampleService                                                                            .__      ____  ___    ________        _____  ______  |    |      ____   _/  __  \\    \/    /\__    \    /          \\____  \|    |  _/  __  \   \    ___/  >        <    /  __  \|    Y  Y    \    |_>  >    |_\    ___/    \___    >__/\_  \(____    /__|_|    /      __/|____/\___    >            \/            \/          \/            \/|__|                          \/     WARN    [2014-­‐04-­‐25  15:11:30,520]  io.dropwizard.setup.AdminEnvironment:   !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!   !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!   !        THIS  APPLICATION  HAS  NO  HEALTHCHECKS.  THIS  MEANS  YOU  WILL  NEVER  KNOW            !   !          IF  IT  DIES  IN  PRODUCTION,  WHICH  MEANS  YOU  WILL  NEVER  KNOW  IF  YOU'RE            !   !        LETTING  YOUR  USERS  DOWN.  YOU  SHOULD  ADD  A  HEALTHCHECK  FOR  EACH  OF  YOUR        !   !                  APPLICATION'S  DEPENDENCIES  WHICH  FULLY  (BUT  LIGHTLY)  TESTS  IT.              !   !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!   !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!  
  21. None
  22. Configuration class Application class Representation classes Resource classes Health check

    classes Rails.application.config Application class Views + Jbuilder/gem Controllers + Routes Gem/addon
  23. None
  24. None
  25. None
  26. $  mvn  clean  package   $  java  -­‐jar  target/helloworld.jar  server

     server.yml     INFO    [2014-­‐04-­‐15  06:18:35,695]  io.dropwizard.server.ServerFactory:  Starting   SampleService   INFO    [2014-­‐04-­‐15  06:18:35,947]  io.dropwizard.jersey.DropwizardResourceConfig:  The   following  paths  were  found  for  the  configured  resources:            GET          /hello-­‐world/{name}  (com.example.helloworld.resources.HelloWorldResource)     INFO    [2014-­‐04-­‐15  06:18:36,166]  io.dropwizard.setup.AdminEnvironment:  tasks  =            POST        /tasks/gc  (io.dropwizard.servlets.tasks.GarbageCollectionTask)     INFO    [2014-­‐04-­‐15  06:18:36,175]  org.eclipse.jetty.server.ServerConnector:  Started   application@29a19259{HTTP/1.1}{0.0.0.0:8080}   INFO    [2014-­‐04-­‐15  06:18:36,176]  org.eclipse.jetty.server.ServerConnector:  Started   admin@2e8f2669{HTTP/1.1}{0.0.0.0:8081}  
  27. $  curl  http://0.0.0.0:8080/hello-­‐world/mundo  -­‐I     HTTP/1.1  200  OK  

    Date:  Tue,  15  Apr  2014  05:02:25  GMT   Cache-­‐Control:  no-­‐transform,  max-­‐age=86400   Content-­‐Type:  text/plain   Vary:  Accept-­‐Encoding   Transfer-­‐Encoding:  chunked     Hello,  mundo!  
  28. None
  29. $  curl  http://0.0.0.0:8081/healthcheck?pretty=true  -­‐I     HTTP/1.1  500  Server  Error

      Date:  Tue,  15  Apr  2014  04:53:33  GMT   Content-­‐Type:  application/json   Cache-­‐Control:  must-­‐revalidate,no-­‐cache,no-­‐store   Content-­‐Length:  172     {      "deadlocks"  :  {          "healthy"  :  true      },      "random"  :  {          "healthy"  :  false,          "message"  :  "Not  one,  how  can  I  possibly  serve  traffic?"      }   }  
  30. $  curl  http://0.0.0.0:8081/healthcheck?pretty=true  -­‐I     HTTP/1.1  200  OK  

    Date:  Tue,  15  Apr  2014  04:54:32  GMT   Content-­‐Type:  application/json   Cache-­‐Control:  must-­‐revalidate,no-­‐cache,no-­‐store   Content-­‐Length:  87     {      "deadlocks"  :  {          "healthy"  :  true      },      "random"  :  {          "healthy"  :  true      }   }  
  31. None
  32. None
  33. Look at how another framework solves problems Choose the right

    stack to build on Apply the good parts back to our Ruby/Rails apps
  34. None
  35. None
  36. process_action.action_controller deliver.action_mailer sql.active_record cache_read.active_support cache_write.active_support render_template.action_view

  37. None
  38. Run statsd on each instance Calculate percentiles: p75, p90, p95,

    and p99 Report somewhere to make dashboards and pretty graphs
  39. None
  40. Looks like we rotate logs at the same time every

    night. Goodbye I/O.
  41. None
  42. Query the database? Pull from the cache? Talk to an

    external service? Log an event? Queue a message? Send an email?
  43. None
  44. None
  45. None
  46. Look at how another framework solves problems Choose the right

    stack to build on Apply the good parts back to our Ruby/Rails apps
  47. None
  48. Runbook Health check Easily deployable Circuit breakers PagerDuty alerts Metrics

    Logging & rotation Exception tracking Configuration repo HA configuration Backups Disaster recovery Process control CI build Code coverage
  49. None
  50. Probably Yes Yes Yes It helps ? ?

  51. None
  52. None
  53. Fast or frequent development iterations To aggregate sequential sources or

    a single source Expressiveness for business rules or through a DSL To perform tasks asynchronously
  54. To be in the critical performance path True parallelization of

    tasks or gathering of data Support for lots of concurrent connections Large heaps to keep things in memory
  55. Stable API Parallelization Critical performance Fast/frequent dev All data in

    payload Performs tasks async Convention/DSL based Concurrent connections
  56. For many things we’ve done, Rails has proven more beneficial

    than other Ruby alternatives We’re not satisfied with that as an answer, its just the state of the world today Last year we pretty much had 1-‐2 Rails apps, today we have 5-‐6 and more underway
  57. None
  58. None
  59. None
  60. None
  61. None
  62. Brian Morton / @brianxq3 eng.yammer.com