O documento discute as opções de servidores de aplicação e web para aplicações Ruby on Rails. Ele explica como servidores como Unicorn, Puma e Phusion Passenger funcionam e quais frameworks eles suportam. O documento também fornece dicas sobre como configurar corretamente o número de workers para obter o melhor desempenho.
7. Qual o papel dos app servers?
• Accept/parse de requisições
• Comunicar a web app
através da abstração Rack
• Converter a resposta da
interface Rack (que a web
app retorna)
12. • Fácil de trabalhar!
• Sem complexidade de
multithreading!
• Maior consumo de mem.
RAM para concorrência!
• Slow Clients podem
atrasar seu funcionamento
Processo 1 Processo 2 Processo 3
Request Request
Request
MultiProcess Blocking
13. • Menos suscetível ao
problema causado por
Slow Clients
• Código precisa ser
thread safe
• Rails se declarou
thread safe em 2008 na
versão 2.2
Processo 1
Request
Processo 2 Processo 3
MultiThreading Blocking
14. • Concorrência ilimitada
• Não consome tanta mem. RAM
• Imune à Slow Clients
• Requer que app e libs tenham
sido escritas tendo em mente o
Evented I/O Copyright Benjamin Erb
Evented
15. • Pre-forking worker model com I/O
bloqueante!
• Copy-on-Write (Ruby 2.0+)!
• Evita concorrência (mas a app pode utilizar
threads internamente)!
• Filosofia "Pior é melhor” !
• Respeita sinais unix muito bem!
• Não lida bem com ‘slow clients'
Unicorn
16. Processo 1 Processo 2 Processo 3 Processo N
Slow
Client
Client
Slow
Client
Slow
Client
Slow
Client
Client
Fila de requisições!
…
Slow clients?
17. • Buffer de requisições HTTP (e grande responses)!
• Gasta o menor tempo possível do userspace!
• Serializa I/O de rede um processo do userspace!
• Gerencia bem conexões persistentes (HTTP 1.1)!
• Deve servir arquivos estáticos
userspace:!
Todo código que roda fora da área de memória virtual das
tarefas do Kernel
Reverse Proxying
18. • Baseado no Unicorn
• Desenvolvido para atender apps
que esperam longo tempo de
requisição/resposta
Modelos de Concorrência de Rede!
• Coolio!
• CoolioFiberSpawn!
• CoolioThreadPool!
• CoolioThreadSpawn!
• Epoll!
• EventMachine!
• FiberPool!
• FiberSpawn!
• (etc)
Rainbows!
21. Quantos workers devo utilizar no Unicorn?
Quanto mais requests, mais
worker_processes
Quanto mais worker_processes,
mais mem. RAM
Copyright DigitalOcean
Memory leak?
22. group :production do
gem 'unicorn'
gem 'unicorn-worker-killer'
end
if ENV['RAILS_ENV'] == 'production'
require 'unicorn/worker_killer'
!
max_request_min = 500
max_request_max = 600
!
# Max requests per worker
use Unicorn::WorkerKiller::MaxRequests, max_request_min, max_request_max
end
Unicorn Killer
23. • Inspirado no Mongrel
• Suporta “verdadeiro paralelismo”
• Funciona muito bem com Rubinius e JRuby
• Evented I/O
• Thread Pool
• Clustered Mode
Puma
24. • Utiliza todos os cores da CPU disponíveis!
• Built-in buffering reverse proxy (Evented I/O)!
• Inicia e elimina processos da aplicação de acordo com
o tráfego!
• Utiliza preloading e copy-on-write!
• HTTP cache integrado!
• Garbage collection entre requests
Passenger (a.k.a Raptor)
25. • passenger_max_pool_size (compartilhado entre apps)
• passenger_min_instances (mínimo por app)
• passenger_pool_idle_time (quanto tempo manter worker vivo)
max_app_processes = (TOTAL_RAM * 0.75) / RAM_PER_PROCESS
max_app_threads_per_process =
((TOTAL_RAM * 0.75) - (NUMBER_OF_CPUS * RAM_PER_PROCESS * 0.9)) /
(RAM_PER_PROCESS / 10)
25% livre para o SO
E o número de workers?
26. Posso usar qualquer app server?
Não!
• Blocking I/O: Aumente o número de processos/threads
• CPU-bound: configure conforme o número de CPUs e evite
swap
• Dê preferência a usar Nginx como web server