Otimizando Aplicações em Rails

1,284 views
1,189 views

Published on

por Juan Maiz e Pedro Axelrud

Published in: Technology, Travel
0 Comments
2 Likes
Statistics
Notes
  • Be the first to comment

No Downloads
Views
Total views
1,284
On SlideShare
0
From Embeds
0
Number of Embeds
132
Actions
Shares
0
Downloads
11
Comments
0
Likes
2
Embeds 0
No embeds

No notes for slide

Otimizando Aplicações em Rails

  1. 1. Otimizando Aplicações em Rails essa palestra será rápida
  2. 2.  Servidor Active Record / SQL Ruby / Rails Cache BackgrounDRb Metal HTML, JS & CSS
  3. 3. Nginx, Apache balanceadores de carga
  4. 4. joeandmotorboat.com/2008/02/28/apache-vs-nginx-web-server-performance-deathmatch/
  5. 5. Mongrel, Thin, Passenger servidores de aplicação
  6. 6. http://izumi.plan99.net/blog/index.php/2008/03/31/benchmark-passenger-mod_rails-vs-mongrel-vs-thin/
  7. 7. Active Record / SQL
  8. 8. INCLUDE for list in List.all ... do some ... for contact in list.contacts ... do some ... end end
  9. 9. INCLUDE for list in List.all(:include => :contacts) ... do some ... for contacts in list.contacts ... do some ... end end
  10. 10. ÍNDICES Rails não adiciona índices nas tabelas EXPLAIN ANALYZE SELECT * FROM contacts WHERE email = 'foo@bar.com';>> cost=0.00..25.38CREATE INDEX contacts_email_idx    ON contacts(email);>> cost=0.00..1.06
  11. 11. TABELAS CONSOLIDADAS 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  
  12. 12. CSV EXPORT COPY (SELECT * FROM contacts) TO 'path' WITH DELIMITER ';' CSV HEADER Muitas ordens de magnitude mais rápido do que AR + FasterCSV
  13. 13. WORKING ON postgres_timestamps plugin sobrescreve comportamento de created_at e updated_at do AR cria defaults e triggers automaticamente nas migrações benchmarks 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!    
  14. 14. Ruby / Rails
  15. 15. BENCHMARK require 'benchmark'   Benchmark.bm do |x| x.report('foo') { ... code ... } x.report('bar') { ... code ... } end
  16. 16. ||= def calculate_something @something = do_some_heavy_calculation end
  17. 17. MEMOIZE def calculate_something(*args) do_some_heavy_calculation end memoize :calculate_something calculate_something(1) #Hit calculate_something(1) #Cache calculate_something(1) #Cache calculate_something(2) #Hit
  18. 18. RAILS STARTUP # environment startup file require 'geoip_city' GEOIPDB = GeoIPCity::Database.new('file.dat') # some controller or model GEOIPDB.look_up(ip)
  19. 19. DICAS GERAIS ids = @contacts.map(&:id) #bad ids = @contacts.map{|c| c.id} #ugly, but good str = str.gsub(/java/, 'ruby')#bad str.gsub!(/java/, 'ruby') #good
  20. 20. Cache
  21. 21. PAGE CACHE # site controller caches_page :index
  22. 22. ACTION CACHE # login controller before_filter :get_client caches_action :index
  23. 23. FRAGMENT CACHE # some view - cache :action_suffix => 'comments' do = render :partial => 'comments' # no controller... def create_comment ... expire_fragment :action => 'show_post', :action_suffix => 'comments' end
  24. 24. FRAGMENT CACHE # some view - cache :key => @contact.updated_at do = render :partial => 'contact_info' # Expira automático, mas gera alguns arquivos ...
  25. 25. HTTP CLIENT CACHE fresh_when     :last_modified => @product.published_at.utc,     :etag => @article
  26. 26. CACHE-MONEY PLUGIN http://github.com/nkallen/ cache-money/tree/master     >> Try it out and tell us...  
  27. 27. Metal
  28. 28. METAL 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 end end
  29. 29. METAL 2-5x faster >> NÃO DEVERIA SE CHAMAR SPEED METAL?
  30. 30. BackgrounDRb
  31. 31. Pode executar tarefas em bg; Pode agendar tarefas para executar em bg; Pode executar tarefas periodicamente em bg; Pode até conversar via TCP;
  32. 32. EXECUTANDO UMA TAREFA 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 end end # start worker on controller MiddleMan.worker(:contacts_worker).async_delete(:args => {:contacts => @contacts}, :job_key => @job_key) # verify worker status via Ajax t = MiddleMan.worker(:contacts_worker).ask_result(:total) c = MiddleMan.worker(:contacts_worker).ask_result(:curr) return render :json => [t, c]
  33. 33. EXECUTANDO UMA TAREFA Média antes: 13s (muitas FKs! milhares de contatos!) Média depois: 0.1s (usuário pode trabalhar durante processo)
  34. 34. EXECUTANDO UMA TAREFA AGENDADA MiddleMan.worker(:messenger_worker) .enq_send_messages( :args => @message.id, :scheduled_at => @message.scheduled_at, :job_key => "message_#{@message.id}")
  35. 35. EXECUTANDO UMA TAREFA PERIÓDICA # backgroundrb.yml :schedules: :table_cache_worker: :table_cache: :trigger_args: 0 30 4 * * * *
  36. 36. HTML, JS & CSS
  37. 37. CSS PLEASE DONT USE FONT TAG SPRITES * JSMIN GZIP HTTP CLIENT CACHE (304!) return render :nothing => true, :status => 304
  38. 38. Cloud Storage e CDN static.mailee.me

×