Fisl 11 - Dicas de Desenvolvimento Web com Ruby

Post on 08-May-2015

1.863 views 3 download

description

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.

Transcript of Fisl 11 - Dicas de Desenvolvimento Web com Ruby

RubyA apresentação já vai começar ...

AkitaOnRails.com

@AkitaOnRails

Entendendo a WebDicas sobre Desenvolvimento Web com Ruby

Fabio Akita

Recapitulando ...

Rails não Escala

Rails não Escala(TM)

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

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

Quando as pessoas caem em problemas de escalabilidade, normalmente acham que a

linguagem é o problema, mas eu acho que isso raramente é a

realidade.

http://www.computerworld.com.au/article/268003/ruby_rails_rolls_into_enterprise?fp=16&fpid=1

“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

“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.”

Web Server

MySQL

Browser

Web Server

MySQL

Browser

Varnish/HAProxy

Web Server

MySQL

Browser

Varnish/HAProxy

Memcached

Web Server

MySQL

Browser

Varnish/HAProxy

Memcached

CouchDB/MongoDB

Ruby é Lento

Ruby é Lento(TM)

Existem mentiras, mentiras malditas e

estatísticas.

Existem mentiras, mentiras malditas e

estatísticas.

Existem mentiras, mentiras malditas e

estatísticas.

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

x mais lento que C++

Homepage: 331 ms

Homepage: 331 ms

Total: 5.45 s

Performance!=

Escalabilidade

Sempre se Lembre

Poderíamos contratar um Macaco Treinadopara fazer seu Trabalho!

Exemplo

6Técnicas

Menos Requisições

Mini!que CSS e Javascript

Juicerhttp://github.com/cjohansen/juicer/

gem install juicer

script/plugin install git://github.com/ktheory/juicer-rails.git

gem install juicer

script/plugin install git://github.com/ktheory/juicer-rails.git

juicer install yuicompressor

juicer install jslint

juicer install closure_compiler

juicer install yuicompressor

juicer install jslint

juicer install closure_compiler

juicer install yuicompressor

juicer install jslint

juicer install closure_compiler

<%= juiced_tag '/stylesheets/application.css' %> <%= yield(:head) %>

</head><body>

... <%= juiced_tag '/javascripts/application.js' %>

</body>

/app/views/layouts/application.html.erb

<%= juiced_tag '/stylesheets/application.css' %> <%= yield(:head) %>

</head><body>

... <%= juiced_tag '/javascripts/application.js' %>

</body>

/app/views/layouts/application.html.erb

@import url("reset.css");@import url("base.css");@import url("fonts.css");

...

/* @depends jquery-1.4.min.js @depends jquery.edit_in_place.js @depends jqueryamail.js*/

...

/public/stylesheets/application.css

/public/javascripts/application.js

@import url("reset.css");@import url("base.css");@import url("fonts.css");

...

/* @depends jquery-1.4.min.js @depends jquery.edit_in_place.js @depends jqueryamail.js*/

...

/public/stylesheets/application.css

/public/javascripts/application.js

juicer merge public/stylesheets/application.css

public/stylesheets/application.min.css

juicer merge -i public/javascripts/application.js

public/javascripts/application.min.js

juicer merge public/stylesheets/application.css

public/stylesheets/application.min.css

juicer merge -i public/javascripts/application.js

public/javascripts/application.min.js

juicer merge public/stylesheets/application.css

public/stylesheets/application.min.css

juicer merge -i public/javascripts/application.js

public/javascripts/application.min.js

juicer merge public/stylesheets/application.css

public/stylesheets/application.min.css

juicer merge -i public/javascripts/application.js

public/javascripts/application.min.js

DEVELOPMENT

PRODUCTION

Asset HostsNavegadores abrem poucas conexões

simultâneas por domínio

def gallery gallery_path = File.join(Rails.root, "public/images/gallery/")

@images = Dir.glob(gallery_path + "*").map{ |f| f.gsub(gallery_path, "") }

end

/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/controllers/hello_controller.rb

/app/views/hello/gallery.html.erb

<% title "Gallery" %>

<% @images.each do |image| -%> <%= image_tag "gallery/#{image}" %>

<% end -%>

def gallery gallery_path = File.join(Rails.root, "public/images/gallery/")

@images = Dir.glob(gallery_path + "*").map{ |f| f.gsub(gallery_path, "") }

end

/app/controllers/hello_controller.rb

/app/views/hello/gallery.html.erb

<% title "Gallery" %>

<% @images.each do |image| -%> <%= image_tag "gallery/#{image}" %>

<% end -%>

DEVELOPMENT

DEVELOPMENT

/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

/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

### Host Database## localhost is used to configure the loopback interface# when the system is booting. Do not change this entry.##127.0.0.1 localhost255.255.255.255 broadcasthost::1 localhost fe80::1%lo0 localhost127.0.0.1 asset1.akitaonrails.local asset2.akitaonrails.local asset3.akitaonrails.local asset4.akitaonrails.local asset5.akitaonrails.local asset6.akitaonrails.local www.akitaonrails.local

/etc/hosts

PRODUCTION

PRODUCTION

Javascript embaixo!

<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>...

/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>...

/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>

/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>

/app/views/layouts/application.html.erb

Gzip

a2enmod de"ate

editar/etc/apache2/mods-available/de"ate.conf

a2enmod de"ate

editar/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>

/etc/apache2/mods-available/de"ate.conf

Cabeçalhos de Expiração

a2enmod expires

editar/etc/apache2/mods-available/expires.conf

a2enmod expires

editar/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>

/etc/apache2/mods-available/expires.conf

Cache Busters

<%= stylesheet_link_tag 'application' %>

<%= javascript_include_tag 'application' %>

<%= image_tag "logo.png" %>

/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" />

/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" />

/app/views/layouts/application.html.erb

Use CDNs

<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>

/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>

/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>

/app/views/layouts/application.html.erb

Search

select * from ... where ... like “%...%”

select * from ... where ... like “%...%”

or ... like “%...%”or ... like “%...%”or ... like “%...%”or ... like “%...%”

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)

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)

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)

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)

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)

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)

SOLR

Sphinx

Xapian

SOLR

Sphinx

Xapian

SOLR

Sphinx

Xapian

select * from ... where ... like “%...%”

or ... like “%...%”or ... like “%...%”or ... like “%...%”or ... like “%...%”

Tarefas Assíncronas

Requisição

ProcessamentoRequisição

Resposta

ProcessamentoRequisição

Crontab

RMagick

RedisWorkers

Resque-Web

ProcessamentoRequisição

291 ms

Resposta

Processamento

Requisição

32 ms

Worker

Resque Redis

Delayed Job SQL

Warren RabbitMQ

Whenever Cron Jobs

Resque Redis

Delayed Job SQL

Warren RabbitMQ

Whenever Cron Jobs

Resque Redis

Delayed Job SQL

Warren RabbitMQ

Whenever Cron Jobs

Resque Redis

Delayed Job SQL

Warren RabbitMQ

Whenever Cron Jobs

Imagens

Relatórios

Web Services

Transações

Imagens

Relatórios

Web Services

Transações

Imagens

Relatórios

Web Services

Transações

Imagens

Relatórios

Web Services

Transações

Aprendendo Mais

RAILS LABS

RAILSCASTS.com

caelum.com.br

egenial.com.br

Entenda os browsers

Entenda HTTP

Arquiteturas

Mundo Assíncrono

Mundo não Relacional

Entenda os browsers

Entenda HTTP

Arquiteturas

Mundo Assíncrono

Mundo não Relacional

Entenda os browsers

Entenda HTTP

Arquiteturas

Mundo Assíncrono

Mundo não Relacional

Entenda os browsers

Entenda HTTP

Arquiteturas

Mundo Assíncrono

Mundo não Relacional

Entenda os browsers

Entenda HTTP

Arquiteturas

Mundo Assíncrono

Mundo não Relacional