O documento discute diferentes opções de servidores de aplicação para Ruby on Rails, incluindo Unicorn, Puma e Passenger. Explica os modelos de I/O bloqueante, multithreading e event-driven, e como cada servidor se encaixa nesses modelos. Também fornece recomendações sobre como escolher e configurar um servidor de aplicação para diferentes tipos de aplicações.
7. Globalcode – Open4education
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. Globalcode – Open4education
MultiProcess Blocking
• 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
13. Globalcode – Open4education
MultiThreading Blocking
• 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
14. Globalcode – Open4education
Evented
• 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
15. Globalcode – Open4education
Unicorn
• Pre-forking worker model com I/O
bloqueante
• Copy-on-Write
• 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'
16. Globalcode – Open4education
Pre-Forking e Copy-on-Write
Master200 MB Master Child 2
Write
Pre-forking
Request Ruby 2.0+
Essa feature só foi implementada no
Garbage Collector do Ruby 2.0+
17. Globalcode – Open4education
Client
Slow Clients?
Processo 1 Processo 2 Processo 3 Processo N
Slow
Client
Client
Slow
Client
Slow
Client
Slow
Client
Client
Fila de requisições
…
20. Globalcode – Open4education
Reverse Proxying
• 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
21. Globalcode – Open4education
Rainbows
http://rainbows.bogomips.org/
• 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)
22. Globalcode – Open4education
Threads e Eventos são
difíceis
• Unicorn evita concorrência em cada worker
• Para atender mais requisições, aumentamos o número de
workers
worker_processes
É muito importante saber quanto memória RAM sua app
precisa para definir este número
26. Globalcode – Open4education
Quantos workers devo
utilizar no Unicorn?
• Quanto mais requests, mais worker_processes
• Quanto mais worker_processes, mais mem RAM
Copyright DigitalOcean
Memory leak?
27. Globalcode – Open4education
Unicorn Killer
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
28. Globalcode – Open4education
Puma
• Inspirado no Mongrel
• Suporta “verdadeiro paralelismo”
• Funciona muito bem com Rubinius e JRuby
• Evented I/O
• Thread Pool
• Clustered Mode
29. Globalcode – Open4education
É rápido?
PUMA - 78 Mb RAINBOWS! (1X16) - 120 Mb
UNICORN - 1076 Mb RAINBOWS! (16X32) - 1138 Mb
Requests/sec x Number of concurrent requests
32. Globalcode – Open4education
Ruby Raptor aka Passenger 5
• 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
34. Globalcode – Open4education
E o número de workers do
Passenger?
• 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
35. Globalcode – Open4education
Para qualquer app?
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 ao Nginx, não se preocupe em configurar
https://www.phusionpassenger.com/documentation/Users%20guide%20Apache.html