otimizando aplicações em rails

39
Otimizando Aplicações em Rails essa palestra será rápida

Upload: juan-maiz

Post on 15-Jul-2015

1.122 views

Category:

Technology


4 download

TRANSCRIPT

Page 1: Otimizando Aplicações em Rails

Otimizando Aplicações em Rails

essa palestra será rápida

Page 2: Otimizando Aplicações em Rails

 ServidorActive Record / SQLRuby / RailsCacheBackgrounDRb MetalHTML, JS & CSS

Page 3: Otimizando Aplicações em Rails
Page 4: Otimizando Aplicações em Rails

Nginx, Apache

balanceadores de carga

Page 5: Otimizando Aplicações em Rails

joeandmotorboat.com/2008/02/28/apache-vs-nginx-web-server-performance-deathmatch/

Page 6: Otimizando Aplicações em Rails

Mongrel, Thin, Passenger

servidores de aplicação

Page 7: Otimizando Aplicações em Rails

http://izumi.plan99.net/blog/index.php/2008/03/31/benchmark-passenger-mod_rails-vs-mongrel-vs-thin/

Page 8: Otimizando Aplicações em Rails

Active Record / SQL

Page 9: Otimizando Aplicações em Rails

for list in List.all ... do some ... for contact in list.contacts ... do some ... endend

INCLUDE

Page 10: Otimizando Aplicações em Rails

for list in List.all(:include => :contacts) ... do some ... for contacts in list.contacts ... do some ... endend

INCLUDE

Page 11: Otimizando Aplicações em Rails

Rails não adiciona índices nas tabelasEXPLAIN ANALYZE SELECT * FROM contacts WHERE email = '[email protected]';>> cost=0.00..25.38CREATE INDEX contacts_email_idx    ON contacts(email);>> cost=0.00..1.06

ÍNDICES

Page 12: Otimizando Aplicações em Rails

Newsletter#history>> Buscava dados de mais de 100 mensagens (total de envios, acessos, cliques, descadastros, informações geográficas...) em uma view e apresentava um gráfico.

Tempo médio do método: 18s CREATE TABLE messages_complete_history AS SELECT * FROM view_messages_complete_history;

Tempo médio do método: 0.3s >> Criação agendada para a madrugada com BackgroundRB   

TABELAS CONSOLIDADAS

Page 13: Otimizando Aplicações em Rails

COPY (SELECT * FROM contacts) TO 'path' WITH DELIMITER ';' CSV HEADER

Muitas ordens de magnitude mais rápido do que AR + FasterCSV

CSV EXPORT

Page 14: Otimizando Aplicações em Rails

postgres_timestamps pluginsobrescreve comportamento de created_at e updated_at do ARcria defaults e triggers automaticamente nas migraçõesbenchmarks que fiz: de 2 a 5% mais rápido em 1000 inserts. até 10% mais rápido em 1000 updates;

 >> Prometo para ainda este ano!  

WORKING ON

Page 15: Otimizando Aplicações em Rails

Ruby / Rails

Page 16: Otimizando Aplicações em Rails

require 'benchmark' Benchmark.bm do |x|x.report('foo') { ... code ... }x.report('bar') { ... code ... }end

BENCHMARK

Page 17: Otimizando Aplicações em Rails

def calculate_something @something = do_some_heavy_calculation end

||=

Page 18: Otimizando Aplicações em Rails

def calculate_something(*args) do_some_heavy_calculationendmemoize :calculate_something calculate_something(1) #Hit calculate_something(1) #Cachecalculate_something(1) #Cache calculate_something(2) #Hit

MEMOIZE

Page 19: Otimizando Aplicações em Rails

# environment startup file require 'geoip_city'GEOIPDB = GeoIPCity::Database.new('file.dat') # some controller or modelGEOIPDB.look_up(ip)

RAILS STARTUP

Page 20: Otimizando Aplicações em Rails

ids = @contacts.map(&:id) #badids = @contacts.map{|c| c.id} #ugly, but good

str = str.gsub(/java/, 'ruby')#badstr.gsub!(/java/, 'ruby') #good

DICAS GERAIS

Page 21: Otimizando Aplicações em Rails

Cache

Page 22: Otimizando Aplicações em Rails

# site controllercaches_page :index

PAGE CACHE

Page 23: Otimizando Aplicações em Rails

# login controllerbefore_filter :get_clientcaches_action :index

ACTION CACHE

Page 24: Otimizando Aplicações em Rails

# some view- cache :action_suffix => 'comments' do = render :partial => 'comments' # no controller...def create_comment ... expire_fragment :action => 'show_post', :action_suffix => 'comments'end

FRAGMENT CACHE

Page 25: Otimizando Aplicações em Rails

# some view- cache :key => @contact.updated_at do = render :partial => 'contact_info'# Expira automático, mas gera alguns arquivos ...

FRAGMENT CACHE

Page 26: Otimizando Aplicações em Rails

fresh_when    :last_modified => @product.published_at.utc,    :etag => @article

HTTP CLIENT CACHE

Page 27: Otimizando Aplicações em Rails

http://github.com/nkallen/cache-money/tree/master

  >> Try it out and tell us... 

CACHE-MONEY PLUGIN

Page 28: Otimizando Aplicações em Rails

Metal

Page 29: Otimizando Aplicações em Rails

class Go def self.call(env) if env["PATH_INFO"] =~ /^\/go\/view\/(\d+)/ id = $1 request = Rack::Request.new(env) delivery = Delivery.find id View.create :contact_id => delivery.contact_id, :message_id => delivery.message_id, :ip => request.ip delivery.contact.confirm! [200, {"Content-Type" => "text/html"}, [""]] else [404, {"Content-Type" => "text/html"}, ["Not Found"]] end endend

METAL

Page 30: Otimizando Aplicações em Rails

2-5x faster>> NÃO DEVERIA SE CHAMAR SPEED METAL?

METAL

Page 31: Otimizando Aplicações em Rails

BackgrounDRb

Page 32: Otimizando Aplicações em Rails

Pode executar tarefas em bg;Pode agendar tarefas para executar em bg;Pode executar tarefas periodicamente em bg;Pode até conversar via TCP;

Page 33: Otimizando Aplicações em Rails

class ContactsWorker < BackgrounDRb::MetaWorker set_worker_name :contacts_worker def delete(args) total = args[:contacts].size cache[:total] = total cache[:curr] = 0 cache[:msg] = Contact.delete_many(args[:contacts]) do cache[:curr] += 1 end endend # start worker on controller MiddleMan.worker(:contacts_worker).async_delete(:args => {:contacts => @contacts}, :job_key => @job_key)

# verify worker status via Ajaxt = MiddleMan.worker(:contacts_worker).ask_result(:total)c = MiddleMan.worker(:contacts_worker).ask_result(:curr)return render :json => [t, c]

EXECUTANDO UMA TAREFA

Page 34: Otimizando Aplicações em Rails

Média antes: 13s (muitas FKs! milhares de contatos!)Média depois: 0.1s (usuário pode trabalhar durante processo)

EXECUTANDO UMA TAREFA

Page 35: Otimizando Aplicações em Rails

MiddleMan.worker(:messenger_worker).enq_send_messages( :args => @message.id, :scheduled_at => @message.scheduled_at, :job_key => "message_#{@message.id}")

EXECUTANDO UMA TAREFA AGENDADA

Page 36: Otimizando Aplicações em Rails

# backgroundrb.yml:schedules: :table_cache_worker: :table_cache: :trigger_args: 0 30 4 * * * *

EXECUTANDO UMA TAREFA PERIÓDICA

Page 37: Otimizando Aplicações em Rails

HTML, JS & CSS

Page 38: Otimizando Aplicações em Rails

CSS PLEASE DONT USE FONT TAG

SPRITES *JSMINGZIP

HTTP CLIENT CACHE (304!)return render :nothing => true, :status => 304

Page 39: Otimizando Aplicações em Rails

Cloud Storage e CDN

static.mailee.me