Successfully reported this slideshow.
We use your LinkedIn profile and activity data to personalize ads and to show you more relevant ads. You can change your ad preferences anytime.

27

Share

Download to read offline

QConSP 2015 - Dicas de Performance para Aplicações Web

Download to read offline

Antes de pensar em "vamos reescrever tudo na linguagem mais rápida da moda que tudo vai dar certo". Na verdade pra quase todas as aplicações Web, antes veja se você segue este checklist mínimo de 9 dicas. Você vai ver que a maioria não segue esse mínimo antes, e deveria.

Related Books

Free with a 30 day trial from Scribd

See all

Related Audiobooks

Free with a 30 day trial from Scribd

See all

QConSP 2015 - Dicas de Performance para Aplicações Web

  1. 1. DICAS DE PERFORMANCE WEB Fabio Akita @AkitaOnRails
  2. 2. Back EndBrowser Front End Render External Services
  3. 3. 9 DICAS
  4. 4. SLIDESHARE.NET/ AKITAONRAILS
  5. 5. MONITORING
  6. 6. 1.4 MILHOES DEVISITANTES UNICOS!!
  7. 7. Ruby 2.1
  8. 8. Ruby 2.2
  9. 9. CACHING
  10. 10. def  sitemap      sleep  3      @posts  =  Post.select([  :id,  :slug,  :updated_at,  :published_at  ]).published      respond_to  do  |format|          format.xml  {  render  layout:  false  }      end   end Processing  by  ArchivesController#sitemap  as  XML      Rendered  archives/sitemap.xml.builder  (785.5ms)   Completed  200  OK  in  3879.4ms  (Views:  770.4ms  |  ActiveRecord:  18.7ms  |  Solr:  0.0ms)
  11. 11. def  sitemap      @posts  =  cache('sitemap',  :expires_in  =>  12.hours)  {          sleep  3          Post.select([  :id,  :slug,  :updated_at,  :published_at  ]).published      }      respond_to  do  |format|          format.xml  {  render  layout:  false  }      end   end Processing  by  ArchivesController#sitemap  as  XML      Rendered  archives/sitemap.xml.builder  (763.3ms)   Completed  200  OK  in  842.4ms  (Views:  754.2ms  |  ActiveRecord:  13.3ms  |  Solr:  0.0ms)
  12. 12. def  sitemap      @posts  =  cache('sitemap',  :expires_in  =>  12.hours)  {          Post.select([  :id,  :slug,  :updated_at,  :published_at  ]).published      }      if  stale?(last_modified:  @posts.first.updated_at.utc,          etag:  "posts/#{@posts.count}-­‐#{@posts.first.updated_at.utc}")          respond_to  do  |format|              format.xml  {  render  layout:  false  }          end      end   end Processing  by  ArchivesController#sitemap  as  XML   Completed  304  Not  Modified  in  6.2ms  (ActiveRecord:  1.7ms)
  13. 13. 2s!
  14. 14. 198ms!
  15. 15. ASSET PIPELINE
  16. 16. } }
  17. 17. UPLOADS
  18. 18. Browser 1s
  19. 19. BackendBrowser 1s
  20. 20. Image Magick BackendBrowser 1s
  21. 21. S3 Image Magick BackendBrowser 1s
  22. 22. S3 Image Magick BackendBrowser 1s 2 segundos
  23. 23. Browser 1s
  24. 24. Browser 1s S3
  25. 25. BackendBrowser 1s S3
  26. 26. BackendBrowser 1s 200 ms S3
  27. 27. BackendBrowser 1s 200 ms S3 Image Magick 700 ms
  28. 28. #  Gemfile   gem  'cloudinary'   gem  'attachinary'
  29. 29. #  Gemfile   gem  'cloudinary'   gem  'attachinary' #  config/cloudinary.yml   production:      cloud_name:  "sample"      api_key:  "874837483274837"      api_secret:  "a676b67565c6767a6767d6767f676fe1"
  30. 30. #  Gemfile   gem  'cloudinary'   gem  'attachinary' #  config/cloudinary.yml   production:      cloud_name:  "sample"      api_key:  "874837483274837"      api_secret:  "a676b67565c6767a6767d6767f676fe1"#  app/models/user.rb   class  User  <  ActiveRecord::Base      attr_accessible  :name            has_attachment    :avatar      has_attachments  :photos,  maximum:  3   end
  31. 31. #  Gemfile   gem  'cloudinary'   gem  'attachinary' #  config/cloudinary.yml   production:      cloud_name:  "sample"      api_key:  "874837483274837"      api_secret:  "a676b67565c6767a6767d6767f676fe1"#  app/models/user.rb   class  User  <  ActiveRecord::Base      attr_accessible  :name            has_attachment    :avatar      has_attachments  :photos,  maximum:  3   end #  app/views/users/_form.html.slim   =  form_for(@user)  do  |user_form|          =  user_form.text_field(:name)          =  attachinary_file_field_tag  ‘user[avatar]',              @user,  :avatar          =  attachinary_file_field_tag  ‘user[photos]’,              @user,  :photos          =  user_form.submit("Save")
  32. 32. #  Gemfile   gem  'cloudinary'   gem  'attachinary' #  config/cloudinary.yml   production:      cloud_name:  "sample"      api_key:  "874837483274837"      api_secret:  "a676b67565c6767a6767d6767f676fe1"#  app/models/user.rb   class  User  <  ActiveRecord::Base      attr_accessible  :name            has_attachment    :avatar      has_attachments  :photos,  maximum:  3   end #  app/views/users/_form.html.slim   =  form_for(@user)  do  |user_form|          =  user_form.text_field(:name)          =  attachinary_file_field_tag  ‘user[avatar]',              @user,  :avatar          =  attachinary_file_field_tag  ‘user[photos]’,              @user,  :photos          =  user_form.submit("Save") #  app/controllers/users_controller.rb   ...      def  create          @user  =  User.new(params[:user])          @user.save!      end
  33. 33. #  app/views/users/show.html.slim   -­‐  if  user.avatar.present?      =  cl_image_tag(user.avatar.path,  width:  80,  height:  100,  crop:  :thumb,  gravity:  :face)      -­‐  user.photos.each  do  |photo|          =  cl_image_tag(photo.path,  size:  '70x50',  crop:  :fill,  radius:  20) #  Gemfile   gem  'cloudinary'   gem  'attachinary' #  config/cloudinary.yml   production:      cloud_name:  "sample"      api_key:  "874837483274837"      api_secret:  "a676b67565c6767a6767d6767f676fe1"#  app/models/user.rb   class  User  <  ActiveRecord::Base      attr_accessible  :name            has_attachment    :avatar      has_attachments  :photos,  maximum:  3   end #  app/views/users/_form.html.slim   =  form_for(@user)  do  |user_form|          =  user_form.text_field(:name)          =  attachinary_file_field_tag  ‘user[avatar]',              @user,  :avatar          =  attachinary_file_field_tag  ‘user[photos]’,              @user,  :photos          =  user_form.submit("Save") #  app/controllers/users_controller.rb   ...      def  create          @user  =  User.new(params[:user])          @user.save!      end
  34. 34. CDN
  35. 35. AssetsRailsBrowser 1s 5 segundos
  36. 36. Assets RailsBrowser 1s 200 ms 4 segundos
  37. 37. http://d3vam04na8c92l.cloudfront.net/stylesheets/application-6502e5a88f02b90aeb32c2dd21ea37ab.css
  38. 38. http://d3vam04na8c92l.cloudfront.net/stylesheets/application-6502e5a88f02b90aeb32c2dd21ea37ab.css
  39. 39. http://d3vam04na8c92l.cloudfront.net/stylesheets/application-6502e5a88f02b90aeb32c2dd21ea37ab.css
  40. 40. http://d3vam04na8c92l.cloudfront.net/stylesheets/application-6502e5a88f02b90aeb32c2dd21ea37ab.css http://www.mydomain.com/stylesheets/application-6502e5a88f02b90aeb32c2dd21ea37ab.css
  41. 41. http://d3vam04na8c92l.cloudfront.net/stylesheets/application-6502e5a88f02b90aeb32c2dd21ea37ab.css http://www.mydomain.com/stylesheets/application-6502e5a88f02b90aeb32c2dd21ea37ab.css
  42. 42. http://d3vam04na8c92l.cloudfront.net/stylesheets/application-6502e5a88f02b90aeb32c2dd21ea37ab.css http://www.mydomain.com/stylesheets/application-6502e5a88f02b90aeb32c2dd21ea37ab.css
  43. 43. http://d3vam04na8c92l.cloudfront.net/stylesheets/application-6502e5a88f02b90aeb32c2dd21ea37ab.css http://www.mydomain.com/stylesheets/application-6502e5a88f02b90aeb32c2dd21ea37ab.css
  44. 44. http://d3vam04na8c92l.cloudfront.net/stylesheets/application-6502e5a88f02b90aeb32c2dd21ea37ab.css http://www.mydomain.com/stylesheets/application-6502e5a88f02b90aeb32c2dd21ea37ab.css
  45. 45. #  config/environments/production.rb   config.action_controller.asset_host  =  "d3vam04na8c92l.cloudfront.net" <%=  stylesheet_link_tag        "application",  :media  =>  "all"  %>   <%=  javascript_include_tag  "application"  %>   <%=  image_tag("rails.png")  %> <link  href="http://d3vam04na8c92l.cloudfront.net/stylesheets/application-­‐6502e5a88f02b90aeb32c2dd21ea37ab.css"  rel="stylesheet"  />
  46. 46. DATABASE
  47. 47. #  Gemfile   gem  "lol_dba",  group:  :development   #  no  Terminal   bundle  install   bundle  exec  rake  db:find_indexes
  48. 48. #  app/controllers/posts_controller.rb   def  index      @posts  =  Post.all      respond_to  do  |format|          format.html  #  index.html.erb          format.xml    {  render  :xml  =>  @posts  }      end   end
  49. 49. #  app/controllers/posts_controller.rb   def  index      @posts  =  Post.all      respond_to  do  |format|          format.html  #  index.html.erb          format.xml    {  render  :xml  =>  @posts  }      end   end <%  @posts.each  do  |post|  %>      <tr>          <td><%=  post.name  %></td>          <td><%=  post.comments.size  %></td>          <td><%=  link_to  'Show',  post  %></td>          <td><%=  link_to  'Edit',  edit_post_path(post)  %></td>          <td><%=  link_to  'Destroy',  post,  confirm:  'Are  you  sure?',  method:  :delete  %></td>      </tr>   <%  end  %>
  50. 50. #  app/controllers/posts_controller.rb   def  index      @posts  =  Post.all      respond_to  do  |format|          format.html  #  index.html.erb          format.xml    {  render  :xml  =>  @posts  }      end   end <%  @posts.each  do  |post|  %>      <tr>          <td><%=  post.name  %></td>          <td><%=  post.comments.size  %></td>          <td><%=  link_to  'Show',  post  %></td>          <td><%=  link_to  'Edit',  edit_post_path(post)  %></td>          <td><%=  link_to  'Destroy',  post,  confirm:  'Are  you  sure?',  method:  :delete  %></td>      </tr>   <%  end  %> Started  GET  "/posts/"  for  192.168.47.2  at  2015-­‐03-­‐23  18:31:11  +0000   Cannot  render  console  from  192.168.47.2!  Allowed  networks:  127.0.0.1,  ::1,  127.0.0.0/127.255.255.255      ActiveRecord::SchemaMigration  Load  (0.1ms)    SELECT  "schema_migrations".*  FROM  "schema_migrations"   Processing  by  PostsController#index  as  HTML      Post  Load  (0.2ms)    SELECT  "posts".*  FROM  "posts"      Comment  Load  (0.2ms)    SELECT  "comments".*  FROM  "comments"  WHERE  "comments"."post_id"  =  ?    [["post_id",  1]]      Comment  Load  (0.1ms)    SELECT  "comments".*  FROM  "comments"  WHERE  "comments"."post_id"  =  ?    [["post_id",  2]]      Rendered  posts/index.html.erb  within  layouts/application  (25.3ms)   Completed  200  OK  in  679ms  (Views:  666.4ms  |  ActiveRecord:  1.0ms)
  51. 51. #  app/controllers/posts_controller.rb   def  index      @posts  =  Post.all      respond_to  do  |format|          format.html  #  index.html.erb          format.xml    {  render  :xml  =>  @posts  }      end   end <%  @posts.each  do  |post|  %>      <tr>          <td><%=  post.name  %></td>          <td><%=  post.comments.size  %></td>          <td><%=  link_to  'Show',  post  %></td>          <td><%=  link_to  'Edit',  edit_post_path(post)  %></td>          <td><%=  link_to  'Destroy',  post,  confirm:  'Are  you  sure?',  method:  :delete  %></td>      </tr>   <%  end  %> Started  GET  "/posts/"  for  192.168.47.2  at  2015-­‐03-­‐23  18:31:11  +0000   Cannot  render  console  from  192.168.47.2!  Allowed  networks:  127.0.0.1,  ::1,  127.0.0.0/127.255.255.255      ActiveRecord::SchemaMigration  Load  (0.1ms)    SELECT  "schema_migrations".*  FROM  "schema_migrations"   Processing  by  PostsController#index  as  HTML      Post  Load  (0.2ms)    SELECT  "posts".*  FROM  "posts"      Comment  Load  (0.2ms)    SELECT  "comments".*  FROM  "comments"  WHERE  "comments"."post_id"  =  ?    [["post_id",  1]]      Comment  Load  (0.1ms)    SELECT  "comments".*  FROM  "comments"  WHERE  "comments"."post_id"  =  ?    [["post_id",  2]]      Rendered  posts/index.html.erb  within  layouts/application  (25.3ms)   Completed  200  OK  in  679ms  (Views:  666.4ms  |  ActiveRecord:  1.0ms)
  52. 52. Started  GET  "/posts/"  for  192.168.47.2  at  2015-­‐03-­‐23  18:37:31  +0000   Cannot  render  console  from  192.168.47.2!  Allowed  networks:  127.0.0.1,  ::1,  127.0.0.0/127.255.255.255      ActiveRecord::SchemaMigration  Load  (0.1ms)    SELECT  "schema_migrations".*  FROM  "schema_migrations"   Processing  by  PostsController#index  as  HTML      Post  Load  (0.2ms)    SELECT  "posts".*  FROM  "posts"      Comment  Load  (0.2ms)    SELECT  "comments".*  FROM  "comments"  WHERE  "comments"."post_id"  IN  (1,  2)      Rendered  posts/index.html.erb  within  layouts/application  (25.8ms)   Completed  200  OK  in  109ms  (Views:  96.4ms  |  ActiveRecord:  0.9ms) #  app/controllers/posts_controller.rb   def  index      @posts  =  Post.includes(:comments).all      respond_to  do  |format|          format.html  #  index.html.erb          format.xml    {  render  :xml  =>  @posts  }      end   end <%  @posts.each  do  |post|  %>      <tr>          <td><%=  post.name  %></td>          <td><%=  post.comments.size  %></td>          <td><%=  link_to  'Show',  post  %></td>          <td><%=  link_to  'Edit',  edit_post_path(post)  %></td>          <td><%=  link_to  'Destroy',  post,  confirm:  'Are  you  sure?',  method:  :delete  %></td>      </tr>   <%  end  %>
  53. 53. SEARCH
  54. 54. ASYNC JOBS
  55. 55. Browser 1s
  56. 56. BackendBrowser 1s
  57. 57. Tarefa DemoradaBackendBrowser 1s
  58. 58. Tarefa DemoradaBackendBrowser 1s 4 segundos
  59. 59. Browser 1s
  60. 60. BackendBrowser 1s
  61. 61. BackendBrowser 1s Redis
  62. 62. BackendBrowser 1s 200 ms Redis
  63. 63. BackendBrowser 1s 200 ms Redis Tarefa Demorada (Worker) 3.8 segundos
  64. 64. class  VerySlowJob  <  ActiveJob::Base      queue_as  :default          def  perform(*args)          #  Tarefa  Demorada      end   end
  65. 65. class  VerySlowJob  <  ActiveJob::Base      queue_as  :default          def  perform(*args)          #  Tarefa  Demorada      end   end VerySlowJob.perform_later  record
  66. 66. class  VerySlowJob  <  ActiveJob::Base      queue_as  :default          def  perform(*args)          #  Tarefa  Demorada      end   end VerySlowJob.perform_later  record VerySlowJob.set(wait_until:   Date.tomorrow.noon).perform_later(record)
  67. 67. class  VerySlowJob  <  ActiveJob::Base      queue_as  :default          def  perform(*args)          #  Tarefa  Demorada      end   end VerySlowJob.set(wait:  1.week).perform_later(record) VerySlowJob.perform_later  record VerySlowJob.set(wait_until:   Date.tomorrow.noon).perform_later(record)
  68. 68. #  app/workers/report_job.rb   class  ReportJob  <  ActiveJob::Base      queue_as  :default          def  perform(email,  from_date  =  nil,  to_date  =  nil)          now  =  Time.zone.now          from_date  ||=  now  -­‐  1.year          to_date      ||=  now          file_path  =  ModelGigante.generate_excel(from_date,  to_date)          NotifyReportMailer.send(email,  file_path)      end   end
  69. 69. #  app/controllers/reports_controller.rb   #  ...   def  create      ReportJob.perform_later(params[:email],          params[:from_date],  params[:to_date])      flash[:notice]  =  "Report  is  being  generated.          It  will  be  sent  to  your  email."      redirect_to  reports_path   end   #  ... #  app/workers/report_job.rb   class  ReportJob  <  ActiveJob::Base      queue_as  :default          def  perform(email,  from_date  =  nil,  to_date  =  nil)          now  =  Time.zone.now          from_date  ||=  now  -­‐  1.year          to_date      ||=  now          file_path  =  ModelGigante.generate_excel(from_date,  to_date)          NotifyReportMailer.send(email,  file_path)      end   end
  70. 70. ASYNC MESSAGES
  71. 71. http://blog.tryneighborly.com/amazon-sns-for-apns-on-rails/
  72. 72. <!-­‐-­‐  chat.html  -­‐-­‐>   <script  src="//js.pusher.com/2.2/pusher.min.js"></script>   <script>   $(function()  {          var  pusher  =  new  Pusher('YOUR_APP_KEY');          var  channel  =  pusher.subscribe('my-­‐app-­‐chat');          channel.bind('new-­‐message',  function(data)  {                  $('#chat-­‐box').append(data.message);          });   })   </script>
  73. 73. <!-­‐-­‐  chat.html  -­‐-­‐>   <script  src="//js.pusher.com/2.2/pusher.min.js"></script>   <script>   $(function()  {          var  pusher  =  new  Pusher('YOUR_APP_KEY');          var  channel  =  pusher.subscribe('my-­‐app-­‐chat');          channel.bind('new-­‐message',  function(data)  {                  $('#chat-­‐box').append(data.message);          });   })   </script> #  config/initializer/pusher.rb   Pusher.app_id  =  ENV['PUSHER_APP_ID']   Pusher.key        =  ENV['PUSHER_APP_KEY']   Pusher.secret  =  ENV['PUSHER_APP_SECRET']  
  74. 74. <!-­‐-­‐  chat.html  -­‐-­‐>   <script  src="//js.pusher.com/2.2/pusher.min.js"></script>   <script>   $(function()  {          var  pusher  =  new  Pusher('YOUR_APP_KEY');          var  channel  =  pusher.subscribe('my-­‐app-­‐chat');          channel.bind('new-­‐message',  function(data)  {                  $('#chat-­‐box').append(data.message);          });   })   </script> #  config/initializer/pusher.rb   Pusher.app_id  =  ENV['PUSHER_APP_ID']   Pusher.key        =  ENV['PUSHER_APP_KEY']   Pusher.secret  =  ENV['PUSHER_APP_SECRET']   #  app/workers/new_message_worker.rb   require  'pusher'   class  NewMessageWorker      include  Sidekiq::Worker            def  perform(message_id)          @message  =  Message.find(message_id)          Pusher.trigger('my-­‐app-­‐chat',  'new-­‐message',  {:message  =>  @message})      end   end
  75. 75. <!-­‐-­‐  chat.html  -­‐-­‐>   <script  src="//js.pusher.com/2.2/pusher.min.js"></script>   <script>   $(function()  {          var  pusher  =  new  Pusher('YOUR_APP_KEY');          var  channel  =  pusher.subscribe('my-­‐app-­‐chat');          channel.bind('new-­‐message',  function(data)  {                  $('#chat-­‐box').append(data.message);          });   })   </script> #  app/controllers/messages_controller.rb   #  ...   def  create      @message  =  Message.new(params[:message])      if  @messsage.save          NewMessageWorker.perform_async(@message.id)          #  ...   end   #  ... #  config/initializer/pusher.rb   Pusher.app_id  =  ENV['PUSHER_APP_ID']   Pusher.key        =  ENV['PUSHER_APP_KEY']   Pusher.secret  =  ENV['PUSHER_APP_SECRET']   #  app/workers/new_message_worker.rb   require  'pusher'   class  NewMessageWorker      include  Sidekiq::Worker            def  perform(message_id)          @message  =  Message.find(message_id)          Pusher.trigger('my-­‐app-­‐chat',  'new-­‐message',  {:message  =>  @message})      end   end
  76. 76. TUNING RUBY
  77. 77. http://www.infoq.com/news/2014/12/ruby-2.2.0-released
  78. 78. http://www.infoq.com/news/2014/12/ruby-2.2.0-released
  79. 79. • Mark and Sweep GC (1.8+) http://www.infoq.com/news/2014/12/ruby-2.2.0-released
  80. 80. • Mark and Sweep GC (1.8+) • Bitmap Marking GC (1.9.3+) http://www.infoq.com/news/2014/12/ruby-2.2.0-released
  81. 81. • Mark and Sweep GC (1.8+) • Bitmap Marking GC (1.9.3+) • Lazy Sweep GC (2.0.0+) http://www.infoq.com/news/2014/12/ruby-2.2.0-released
  82. 82. • Mark and Sweep GC (1.8+) • Bitmap Marking GC (1.9.3+) • Lazy Sweep GC (2.0.0+) • Restricted Generational GC (RGenGC 2.1.0+) http://www.infoq.com/news/2014/12/ruby-2.2.0-released
  83. 83. • Mark and Sweep GC (1.8+) • Bitmap Marking GC (1.9.3+) • Lazy Sweep GC (2.0.0+) • Restricted Generational GC (RGenGC 2.1.0+) • Restricted Incremental GC (RIncGC 2.2.0+) http://www.infoq.com/news/2014/12/ruby-2.2.0-released
  84. 84. TRADE-OFF: + GC OU + RAM
  85. 85. #  Gemfile   source  'https://rubygems.org'   ruby  "2.2.1"   #  performance  tuning   gem  'escape_utils'   gem  'fast_blank'   gem  'oj'   gem  'oj_mimic_json' http://marianposaceanu.com/articles/improve-rails-performance-by-adding-a-few-gems
  86. 86. #  Gemfile   source  'https://rubygems.org'   if  ENV['RAILS_ENV']  ==  'production'      ruby  '1.9.3',  :engine  =>  'jruby',  :engine_version  =>  '1.7.18'   else      ruby  '2.2.1'   end   gem  'rails',  '4.2.0'   gem  'rails-­‐api'   gem  'srt'   gem  'pg',  platforms:  'mri'   gem  'activerecord-­‐jdbcpostgresql-­‐adapter',  platforms:  'jruby'   gem  'sidekiq'   gem  'dalli'   gem  'puma'   gem  'rack-­‐cache'   gem  'rack-­‐cors',  require:  'rack/cors'   gem  'rails_12factor'   gem  'newrelic_rpm'
  87. 87. #  Gemfile   source  'https://rubygems.org'   if  ENV['RAILS_ENV']  ==  'production'      ruby  '1.9.3',  :engine  =>  'jruby',  :engine_version  =>  '1.7.18'   else      ruby  '2.2.1'   end   gem  'rails',  '4.2.0'   gem  'rails-­‐api'   gem  'srt'   gem  'pg',  platforms:  'mri'   gem  'activerecord-­‐jdbcpostgresql-­‐adapter',  platforms:  'jruby'   gem  'sidekiq'   gem  'dalli'   gem  'puma'   gem  'rack-­‐cache'   gem  'rack-­‐cors',  require:  'rack/cors'   gem  'rails_12factor'   gem  'newrelic_rpm'
  88. 88. #  Gemfile   source  'https://rubygems.org'   if  ENV['RAILS_ENV']  ==  'production'      ruby  '1.9.3',  :engine  =>  'jruby',  :engine_version  =>  '1.7.18'   else      ruby  '2.2.1'   end   gem  'rails',  '4.2.0'   gem  'rails-­‐api'   gem  'srt'   gem  'pg',  platforms:  'mri'   gem  'activerecord-­‐jdbcpostgresql-­‐adapter',  platforms:  'jruby'   gem  'sidekiq'   gem  'dalli'   gem  'puma'   gem  'rack-­‐cache'   gem  'rack-­‐cors',  require:  'rack/cors'   gem  'rails_12factor'   gem  'newrelic_rpm'
  89. 89. #  Gemfile   source  'https://rubygems.org'   if  ENV['RAILS_ENV']  ==  'production'      ruby  '1.9.3',  :engine  =>  'jruby',  :engine_version  =>  '1.7.18'   else      ruby  '2.2.1'   end   gem  'rails',  '4.2.0'   gem  'rails-­‐api'   gem  'srt'   gem  'pg',  platforms:  'mri'   gem  'activerecord-­‐jdbcpostgresql-­‐adapter',  platforms:  'jruby'   gem  'sidekiq'   gem  'dalli'   gem  'puma'   gem  'rack-­‐cache'   gem  'rack-­‐cors',  require:  'rack/cors'   gem  'rails_12factor'   gem  'newrelic_rpm'
  90. 90. 9 DICAS
  91. 91. Monitoring New Relic
  92. 92. Monitoring New Relic Caching Memcache, ETAG
  93. 93. Monitoring New Relic Caching Memcache, ETAG Assets CloudFlare, Cloudinary
  94. 94. Monitoring New Relic Caching Memcache, ETAG Assets CloudFlare, Cloudinary Database PostgreSQL
  95. 95. Monitoring New Relic Caching Memcache, ETAG Assets CloudFlare, Cloudinary Database PostgreSQL Search Elastic
  96. 96. Monitoring New Relic Caching Memcache, ETAG Assets CloudFlare, Cloudinary Database PostgreSQL Search Elastic Async Jobs Sidekiq, Redis
  97. 97. Monitoring New Relic Caching Memcache, ETAG Assets CloudFlare, Cloudinary Database PostgreSQL Search Elastic Async Jobs Sidekiq, Redis Async Messages pusher.com
  98. 98. Monitoring New Relic Caching Memcache, ETAG Assets CloudFlare, Cloudinary Database PostgreSQL Search Elastic Async Jobs Sidekiq, Redis Async Messages pusher.com Auto scale HireFire,AdeptScale
  99. 99. Monitoring New Relic Caching Memcache, ETAG Assets CloudFlare, Cloudinary Database PostgreSQL Search Elastic Async Jobs Sidekiq, Redis Async Messages pusher.com Auto scale HireFire,AdeptScale Rubies Ruby 2.2.1, JRuby
  100. 100. Monitoring New Relic Caching Memcache, ETAG Assets CloudFlare, Cloudinary Database PostgreSQL Search Elastic Async Jobs Sidekiq, Redis Async Messages pusher.com Auto scale HireFire,AdeptScale Rubies Ruby 2.2.1, JRuby Deployment Heroku
  101. 101. OBRIGADO slideshare.net/akitaonrails
  • skosta

    Apr. 12, 2019
  • shimomura

    Oct. 28, 2015
  • cleitonfco

    Jul. 8, 2015
  • diovanemonteiro

    Jun. 11, 2015
  • faelaphoenix

    May. 28, 2015
  • diegomartins7

    Apr. 6, 2015
  • marlosribeiro3

    Mar. 31, 2015
  • JeffersonOtoni

    Mar. 31, 2015
  • fabiomartins88

    Mar. 30, 2015
  • andrefaria

    Mar. 30, 2015
  • brodock

    Mar. 28, 2015
  • frcgabriel

    Mar. 27, 2015
  • otaviomcarvalho

    Mar. 27, 2015
  • powerirs

    Mar. 27, 2015
  • EuclidesFernandes

    Mar. 27, 2015
  • AndersonRobertoPinto

    Mar. 27, 2015
  • petroniocandido

    Mar. 27, 2015
  • wevertongomes2

    Mar. 26, 2015
  • jamersonweb

    Mar. 26, 2015
  • ffontouras

    Mar. 26, 2015

Antes de pensar em "vamos reescrever tudo na linguagem mais rápida da moda que tudo vai dar certo". Na verdade pra quase todas as aplicações Web, antes veja se você segue este checklist mínimo de 9 dicas. Você vai ver que a maioria não segue esse mínimo antes, e deveria.

Views

Total views

3,996

On Slideshare

0

From embeds

0

Number of embeds

121

Actions

Downloads

71

Shares

0

Comments

0

Likes

27

×