Fisl 11 - Dicas de Desenvolvimento Web com Ruby

  • 1,818 views
Uploaded on

Performance de sites não tem a ver com a linguagem usada por baixo. O impacto maior é a arquitetura. Nesta palestra falo sobre YSlow, Resque e Solr como algumas das coisas que podemos fazer para …

Performance de sites não tem a ver com a linguagem usada por baixo. O impacto maior é a arquitetura. Nesta palestra falo sobre YSlow, Resque e Solr como algumas das coisas que podemos fazer para melhorar a performance/escalabilidade de aplicações web.

More in: Technology
  • Full Name Full Name Comment goes here.
    Are you sure you want to
    Your message goes here
    Be the first to comment
No Downloads

Views

Total Views
1,818
On Slideshare
0
From Embeds
0
Number of Embeds
1

Actions

Shares
Downloads
80
Comments
0
Likes
2

Embeds 0

No embeds

Report content

Flagged as inappropriate Flag as inappropriate
Flag as inappropriate

Select your reason for flagging this presentation as inappropriate.

Cancel
    No notes for slide

Transcript

  • 1. Ruby A apresentação já vai começar ...
  • 2. AkitaOnRails.com @AkitaOnRails
  • 3. www.slideshare.net/akitaonrails http://dl.dropbox.com/u/1732133/dicas-de-desenvolvimento-web-com-rails.zip boss@akitaonrails.com
  • 4. Entendendo a Web Dicas sobre Desenvolvimento Web com Ruby Fabio Akita
  • 5. Recapitulando ...
  • 6. Rails não Escala
  • 7. (TM) Rails não Escala
  • 8. Blaine Cook http://www.akitaonrails.com/2008/6/17/chatting-with-blaine-cook-twitter
  • 9. Para colocar as coisas em perspectiva, o Friendster foi escrito em Java e eles mudaram para PHP. MySpace foi escrito em ColdFusion e eles mudaram para ASP.NET. Blaine Cook http://www.akitaonrails.com/2008/6/17/chatting-with-blaine-cook-twitter
  • 10. Para colocar as coisas em perspectiva, o Friendster foi escrito em Java e eles mudaram para PHP. MySpace foi escrito em ColdFusion e eles mudaram para ASP.NET. Quando as pessoas caem em problemas de escalabilidade, normalmente acham que a linguagem é o problema, mas eu acho que isso raramente é a realidade. Blaine Cook http://www.akitaonrails.com/2008/6/17/chatting-with-blaine-cook-twitter
  • 11. “O The New York Times usou Ruby on Rails para agregar, analizar e mostrar os resultados das eleições em quase tempo real em um de seus sites mais acessados de todos os tempos.” http://www.computerworld.com.au/article/268003/ruby_rails_rolls_into_enterprise?fp=16&fpid=1
  • 12. “O The New York Times usou Ruby on Rails para agregar, analizar e mostrar os resultados das eleições em quase tempo real em um de seus sites mais acessados de todos os tempos.” http://www.computerworld.com.au/article/268003/ruby_rails_rolls_into_enterprise?fp=16&fpid=1
  • 13. Browser Web Server MySQL
  • 14. Browser Varnish/HAProxy Web Server MySQL
  • 15. Browser Varnish/HAProxy Web Server Memcached MySQL
  • 16. Browser Varnish/HAProxy Web Server Memcached MySQL CouchDB/MongoDB
  • 17. Ruby é Lento
  • 18. (TM) Ruby é Lento
  • 19. Existem mentiras, mentiras malditas e estatísticas.
  • 20. Existem mentiras, mentiras malditas e estatísticas.
  • 21. Existem mentiras, mentiras malditas e estatísticas.
  • 22. x mais lento que C++
  • 23. x mais lento que C++ 0 32.5 65 97.5 130 Python 2 Ruby 1.9 JRuby Perl Python 3 PHP Ruby 1.8
  • 24. Homepage: 331 ms
  • 25. Homepage: 331 ms Total: 5.45 s
  • 26. Performance != Escalabilidade
  • 27. Sempre se Lembre Poderíamos contratar um Macaco Treinado para fazer seu Trabalho!
  • 28. Exemplo
  • 29. 6 Técnicas
  • 30. Menos Requisições
  • 31. Mini que CSS e Javascript
  • 32. Juicer http://github.com/cjohansen/juicer/
  • 33. gem install juicer script/plugin install git://github.com/ktheory/juicer-rails.git
  • 34. gem install juicer script/plugin install git://github.com/ktheory/juicer-rails.git
  • 35. juicer install yuicompressor juicer install jslint juicer install closure_compiler
  • 36. juicer install yuicompressor juicer install jslint juicer install closure_compiler
  • 37. juicer install yuicompressor juicer install jslint juicer install closure_compiler
  • 38. /app/views/layouts/application.html.erb <%= juiced_tag '/stylesheets/application.css' %> <%= yield(:head) %> </head> <body> ... <%= juiced_tag '/javascripts/application.js' %> </body>
  • 39. /app/views/layouts/application.html.erb <%= juiced_tag '/stylesheets/application.css' %> <%= yield(:head) %> </head> <body> ... <%= juiced_tag '/javascripts/application.js' %> </body>
  • 40. /public/stylesheets/application.css @import url("reset.css"); @import url("base.css"); @import url("fonts.css"); ... /public/javascripts/application.js /* @depends jquery-1.4.min.js @depends jquery.edit_in_place.js @depends jqueryamail.js */ ...
  • 41. /public/stylesheets/application.css @import url("reset.css"); @import url("base.css"); @import url("fonts.css"); ... /public/javascripts/application.js /* @depends jquery-1.4.min.js @depends jquery.edit_in_place.js @depends jqueryamail.js */ ...
  • 42. juicer merge public/stylesheets/application.css public/stylesheets/application.min.css juicer merge -i public/javascripts/application.js public/javascripts/application.min.js
  • 43. juicer merge public/stylesheets/application.css public/stylesheets/application.min.css juicer merge -i public/javascripts/application.js public/javascripts/application.min.js
  • 44. juicer merge public/stylesheets/application.css public/stylesheets/application.min.css juicer merge -i public/javascripts/application.js public/javascripts/application.min.js
  • 45. juicer merge public/stylesheets/application.css public/stylesheets/application.min.css juicer merge -i public/javascripts/application.js public/javascripts/application.min.js
  • 46. DEVELOPMENT
  • 47. PRODUCTION
  • 48. Asset Hosts Navegadores abrem poucas conexões simultâneas por domínio
  • 49. /app/controllers/hello_controller.rb def gallery gallery_path = File.join(Rails.root, "public/images/gallery/") @images = Dir.glob(gallery_path + "*").map{ |f| f.gsub(gallery_path, "") } end
  • 50. /app/controllers/hello_controller.rb def gallery gallery_path = File.join(Rails.root, "public/images/gallery/") @images = Dir.glob(gallery_path + "*").map{ |f| f.gsub(gallery_path, "") } end /app/views/hello/gallery.html.erb <% title "Gallery" %> <% @images.each do |image| -%> <%= image_tag "gallery/#{image}" %> <% end -%>
  • 51. /app/controllers/hello_controller.rb def gallery gallery_path = File.join(Rails.root, "public/images/gallery/") @images = Dir.glob(gallery_path + "*").map{ |f| f.gsub(gallery_path, "") } end /app/views/hello/gallery.html.erb <% title "Gallery" %> <% @images.each do |image| -%> <%= image_tag "gallery/#{image}" %> <% end -%>
  • 52. DEVELOPMENT
  • 53. DEVELOPMENT
  • 54. /con g/environments/production.rb config.action_controller.asset_host = Proc.new do |source, request| protocol = if request.ssl? request.headers["USER_AGENT"] =~ /(Safari)/ ? "http" : "https" else "http" end "#{protocol}://asset#{rand(6) + 1}.akitaonrails.local:3000" end
  • 55. /con g/environments/production.rb config.action_controller.asset_host = Proc.new do |source, request| protocol = if request.ssl? request.headers["USER_AGENT"] =~ /(Safari)/ ? "http" : "https" else "http" end "#{protocol}://asset#{rand(6) + 1}.akitaonrails.local:3000" end
  • 56. /etc/hosts ## # Host Database # # localhost is used to configure the loopback interface # when the system is booting. Do not change this entry. ## 127.0.0.1 localhost 255.255.255.255 broadcasthost ::1 localhost fe80::1%lo0 localhost 127.0.0.1 asset1.akitaonrails.local asset2.akitaonrails.local asset3.akitaonrails.local asset4.akitaonrails.local asset5.akitaonrails.local asset6.akitaonrails.local www.akitaonrails.local
  • 57. PRODUCTION
  • 58. PRODUCTION
  • 59. Javascript embaixo!
  • 60. /app/views/layouts/application.html.erb <head> <title><%= h(yield(:title) || "Untitled") %></title> <%= stylesheet_link_tag 'application' %> <script src="http://ajax.googleapis.com/ajax/libs/jquery/1.4.0/jquery.min.js" type="text/javascript"></script> <script src="http://ajax.googleapis.com/ajax/libs/jqueryui/1.7.2/jquery-ui.min.js" type="text/javascript"></script> <script src="http://ajax.googleapis.com/ajax/libs/swfobject/2.2/swfobject.js" type="text/javascript"></script> <script src="http://ajax.googleapis.com/ajax/libs/chrome-frame/1.0.2/ CFInstall.min.js" type="text/javascript"></script> <%= yield(:head) %> </head> <body> ...
  • 61. /app/views/layouts/application.html.erb <head> <title><%= h(yield(:title) || "Untitled") %></title> <%= stylesheet_link_tag 'application' %> <script src="http://ajax.googleapis.com/ajax/libs/jquery/1.4.0/jquery.min.js" type="text/javascript"></script> <script src="http://ajax.googleapis.com/ajax/libs/jqueryui/1.7.2/jquery-ui.min.js" type="text/javascript"></script> <script src="http://ajax.googleapis.com/ajax/libs/swfobject/2.2/swfobject.js" type="text/javascript"></script> <script src="http://ajax.googleapis.com/ajax/libs/chrome-frame/1.0.2/ CFInstall.min.js" type="text/javascript"></script> <%= yield(:head) %> </head> <body> ...
  • 62. /app/views/layouts/application.html.erb ... <script src="http://ajax.googleapis.com/ajax/libs/jquery/1.4.0/jquery.min.js" type="text/javascript"></script> <script src="http://ajax.googleapis.com/ajax/libs/jqueryui/1.7.2/jquery-ui.min.js" type="text/javascript"></script> <script src="http://ajax.googleapis.com/ajax/libs/swfobject/2.2/swfobject.js" type="text/javascript"></script> <script src="http://ajax.googleapis.com/ajax/libs/chrome-frame/1.0.2/ CFInstall.min.js" type="text/javascript"></script> <script type="text/javascript"> // meu javascript customizado ... </script> </body> </html>
  • 63. /app/views/layouts/application.html.erb ... <script src="http://ajax.googleapis.com/ajax/libs/jquery/1.4.0/jquery.min.js" type="text/javascript"></script> <script src="http://ajax.googleapis.com/ajax/libs/jqueryui/1.7.2/jquery-ui.min.js" type="text/javascript"></script> <script src="http://ajax.googleapis.com/ajax/libs/swfobject/2.2/swfobject.js" type="text/javascript"></script> <script src="http://ajax.googleapis.com/ajax/libs/chrome-frame/1.0.2/ CFInstall.min.js" type="text/javascript"></script> <script type="text/javascript"> // meu javascript customizado ... </script> </body> </html>
  • 64. Gzip
  • 65. a2enmod de ate editar /etc/apache2/mods-available/de ate.conf
  • 66. a2enmod de ate editar /etc/apache2/mods-available/de ate.conf
  • 67. /etc/apache2/mods-available/de ate.conf <IfModule mod_deflate.c> AddOutputFilterByType DEFLATE text/plain AddOutputFilterByType DEFLATE text/html AddOutputFilterByType DEFLATE text/xml AddOutputFilterByType DEFLATE text/css AddOutputFilterByType DEFLATE image/svg+xml AddOutputFilterByType DEFLATE image/x-icon AddOutputFilterByType DEFLATE application/xml AddOutputFilterByType DEFLATE application/xhtml+xml AddOutputFilterByType DEFLATE application/rss+xml AddOutputFilterByType DEFLATE application/javascript AddOutputFilterByType DEFLATE application/x-javascript AddOutputFilterByType DEFLATE application/x-httpd-php AddOutputFilterByType DEFLATE application/x-httpd-fastphp AddOutputFilterByType DEFLATE application/x-httpd-eruby DeflateCompressionLevel 9 # Netscape 4.X has some problems BrowserMatch ^Mozilla/4 gzip-only-text/html # Netscape 4.06-4.08 have some more problems BrowserMatch ^Mozilla/4.0[678] no-gzip # MSIE masquerades as Netscape, but it is fine BrowserMatch bMSIE !no-gzip !gzip-only-text/html </IfModule>
  • 68. Cabeçalhos de Expiração
  • 69. a2enmod expires editar /etc/apache2/mods-available/expires.conf
  • 70. a2enmod expires editar /etc/apache2/mods-available/expires.conf
  • 71. /etc/apache2/mods-available/expires.conf <IfModule mod_expires.c> ExpiresByType image/x-icon "access plus 1 year" ExpiresByType image/png "access plus 1 year" ExpiresByType image/jpg "access plus 1 year" ExpiresByType image/gif "access plus 1 year" ExpiresByType image/jpeg "access plus 1 year" ExpiresByType application/pdf "access plus 1 year" ExpiresByType audio/x-wav "access plus 1 year" ExpiresByType audio/mpeg "access plus 1 year" ExpiresByType video/mpeg "access plus 1 year" ExpiresByType video/mp4 "access plus 1 year" ExpiresByType video/quicktime "access plus 1 year" ExpiresByType video/x-ms-wmv "access plus 1 year" ExpiresByType application/x-shockwave-flash "access 1 month" ExpiresByType text/css "access plus 1 year" ExpiresByType text/javascript "access plus 1 year" </IfModule>
  • 72. Cache Busters
  • 73. /app/views/layouts/application.html.erb <%= stylesheet_link_tag 'application' %> <%= javascript_include_tag 'application' %> <%= image_tag "logo.png" %>
  • 74. /app/views/layouts/application.html.erb <link href="/stylesheets/application.css?1264345891" media="screen" rel="stylesheet" type="text/css" /> <script src="/javascripts/application.js?1264345058" type="text/javascript"></script> <img alt="Logo" src="/images/logo.png?1268943058" />
  • 75. /app/views/layouts/application.html.erb <link href="/stylesheets/application.css?1264345891" media="screen" rel="stylesheet" type="text/css" /> <script src="/javascripts/application.js?1264345058" type="text/javascript"></script> <img alt="Logo" src="/images/logo.png?1268943058" />
  • 76. Use CDNs
  • 77. /app/views/layouts/application.html.erb <script src="/javascripts/jquery-1.4.min.js" type="text/javascript"></script> <script src="/javascripts/jquery-ui-1.7.2.min.js" type="text/javascript"></script> <script src="/javascripts/swfobject-2.2.js" type="text/javascript"></script> <script src="/javascripts/CFInstall-1.0.2.min.js" type="text/javascript"></script>
  • 78. /app/views/layouts/application.html.erb <script src="http://ajax.googleapis.com/ajax/libs/jquery/1.4.0/jquery.min.js" type="text/javascript"></script> <script src="http://ajax.googleapis.com/ajax/libs/jqueryui/1.7.2/jquery-ui.min.js" type="text/javascript"></script> <script src="http://ajax.googleapis.com/ajax/libs/swfobject/2.2/swfobject.js" type="text/javascript"></script> <script src="http://ajax.googleapis.com/ajax/libs/chrome-frame/1.0.2/CFInstall.min.js" type="text/javascript"></script>
  • 79. /app/views/layouts/application.html.erb <script src="http://ajax.googleapis.com/ajax/libs/jquery/1.4.0/jquery.min.js" type="text/javascript"></script> <script src="http://ajax.googleapis.com/ajax/libs/jqueryui/1.7.2/jquery-ui.min.js" type="text/javascript"></script> <script src="http://ajax.googleapis.com/ajax/libs/swfobject/2.2/swfobject.js" type="text/javascript"></script> <script src="http://ajax.googleapis.com/ajax/libs/chrome-frame/1.0.2/CFInstall.min.js" type="text/javascript"></script>
  • 80. Search
  • 81. select * from ... where ... like “%...%”
  • 82. select * from ... where ... like “%...%” or ... like “%...%” or ... like “%...%” or ... like “%...%” or ... like “%...%”
  • 83. Open Source Enterprise Search Platform Baseado no famoso Lucene Full Text Search, com relevância Indexa documentos (Word, PDF, etc) Interface REST Roda em containers de Servlet (Tomcat)
  • 84. Open Source Enterprise Search Platform Baseado no famoso Lucene Full Text Search, com relevância Indexa documentos (Word, PDF, etc) Interface REST Roda em containers de Servlet (Tomcat)
  • 85. Open Source Enterprise Search Platform Baseado no famoso Lucene Full Text Search, com relevância Indexa documentos (Word, PDF, etc) Interface REST Roda em containers de Servlet (Tomcat)
  • 86. Open Source Enterprise Search Platform Baseado no famoso Lucene Full Text Search, com relevância Indexa documentos (Word, PDF, etc) Interface REST Roda em containers de Servlet (Tomcat)
  • 87. Open Source Enterprise Search Platform Baseado no famoso Lucene Full Text Search, com relevância Indexa documentos (Word, PDF, etc) Interface REST Roda em containers de Servlet (Tomcat)
  • 88. Open Source Enterprise Search Platform Baseado no famoso Lucene Full Text Search, com relevância Indexa documentos (Word, PDF, etc) Interface REST Roda em containers de Servlet (Tomcat)
  • 89. SOLR Sphinx Xapian
  • 90. SOLR Sphinx Xapian
  • 91. SOLR Sphinx Xapian
  • 92. select * from ... where ... like “%...%” or ... like “%...%” or ... like “%...%” or ... like “%...%” or ... like “%...%”
  • 93. Tarefas Assíncronas
  • 94. Requisição
  • 95. Processamento Requisição
  • 96. Processamento Requisição Resposta
  • 97. Crontab
  • 98. RMagick
  • 99. Redis Workers Resque-Web
  • 100. 291 ms Processamento Requisição
  • 101. 32 ms Processamento Requisição Resposta Worker
  • 102. Resque Redis Delayed Job SQL Warren RabbitMQ Whenever Cron Jobs
  • 103. Resque Redis Delayed Job SQL Warren RabbitMQ Whenever Cron Jobs
  • 104. Resque Redis Delayed Job SQL Warren RabbitMQ Whenever Cron Jobs
  • 105. Resque Redis Delayed Job SQL Warren RabbitMQ Whenever Cron Jobs
  • 106. Imagens Relatórios Web Services Transações
  • 107. Imagens Relatórios Web Services Transações
  • 108. Imagens Relatórios Web Services Transações
  • 109. Imagens Relatórios Web Services Transações
  • 110. Aprendendo Mais
  • 111. RAILS LABS
  • 112. RAILSCASTS.com
  • 113. caelum.com.br
  • 114. egenial.com.br
  • 115. Entenda os browsers Entenda HTTP Arquiteturas Mundo Assíncrono Mundo não Relacional
  • 116. Entenda os browsers Entenda HTTP Arquiteturas Mundo Assíncrono Mundo não Relacional
  • 117. Entenda os browsers Entenda HTTP Arquiteturas Mundo Assíncrono Mundo não Relacional
  • 118. Entenda os browsers Entenda HTTP Arquiteturas Mundo Assíncrono Mundo não Relacional
  • 119. Entenda os browsers Entenda HTTP Arquiteturas Mundo Assíncrono Mundo não Relacional
  • 120. Thx! www.slideshare.net/akitaonrails http://dl.dropbox.com/u/1732133/dicas-de-desenvolvimento-web-com-rails.zip boss@akitaonrails.com