Post on 08-Aug-2015
Globalcode – Open4education
Ruby - Definindo a quantidade de workers para sua app
Weverton do Couto TimoteoSoftware Developer
Globalcode – Open4education
Qual app server vocês utilizam?
Puma Passenger Unicorn
Globalcode – Open4education
Como funciona um web server?
Web Server
Usuário
HTTP RequestHTTP ResponseGET HTTP/1.1
Accept: text/htmlAccept-Encoding: gzipAccept-Language: en-USConnection: keep-aliveHost: www2.autocargo.com.brUser-Agent: Chrome/42.0.231
HTTP/1.x 200 OK
Date: Sun, 10 May 2015 GMTServer: nginx/1.4.6 (Ubuntu)Cache-Control: max-age=0Content-Type: text/html; charset=utf-8X-Powered-By: Phusion Passenger 4.0.58
Globalcode – Open4education
Qual web server mais utilizado?
Fonte: rails-hosting.com - 2014
Globalcode – Open4education
Qual app server mais utilizado?
Fonte: rails-hosting.com - 2014
Globalcode – Open4education
Rack
Premissa: Todos app servers implementam uma interface Rack.
Sendo assim todos frameworks web funcionam com todos app servers.
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)
Globalcode – Open4education
Rack Handlers
• Ebb
• Fuzed
• Glassfish v3
• Phusion Passenger • Puma
• Reel
• Unicorn • unixrack
• uWSGI
• yahns
Globalcode – Open4education
Web frameworks suportados
• Camping
• Coset
• Espresso
• Halcyon
• Mack
• Maveric
• Merb
• etc
• Racktools::SimpleApplication
• Ramaze
• Ruby on Rails
• Rum
• Sinatra
• Sin
• Vintage
• Wee
Globalcode – Open4education
Qual app server escolher?
Globalcode – Open4education
Modelos de I/O
• MultiProcess Blocking • MultiThreading Blocking • Evented
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
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
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
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'
Globalcode – Open4education
Pre-Forking e Copy-on-Write
Master200 MB Master Child 2Write
Pre-forking
Request Ruby 2.0+
Essa feature só foi implementada no Garbage Collector do Ruby 2.0+
Globalcode – Open4education
Client
Slow Clients?
Processo 1 Processo 2 Processo 3 Processo N
Slow Client
Client
Slow Client
Slow Client
Slow Client
ClientFila de requisições
…
Globalcode – Open4education
Globalcode – Open4education
Pode ser qualquer um!
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
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)
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
Globalcode – Open4education
Consumo de Recursos
• Ruby 2.1 • Rails 3.2 • curl
derailed_benchmarks
https://github.com/schneems/derailed_benchmarks
Globalcode – Open4education
derailed_benchmarks
gem 'derailed_benchmarks', group: :development
$ cat << EOF > perf.rake require 'bundler' Bundler.setup
require 'derailed_benchmarks' require 'derailed_benchmarks/tasks'EOF
Globalcode – Open4education
Medindo uso de memória em uma app Rails
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?
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_maxend
Globalcode – Open4education
Puma
• Inspirado no Mongrel
• Suporta “verdadeiro paralelismo”
• Funciona muito bem com Rubinius e JRuby
• Evented I/O
• Thread Pool
• Clustered Mode
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
Globalcode – Open4education
Heroku recomenda
https://devcenter.heroku.com/articles/rails-unicorn
https://devcenter.heroku.com/articles/deploying-rails-applications-with-the-puma-web-server
Globalcode – Open4education
Por que o Gitlab voltou a utilizar Unicorn?
http://stackoverflow.com/a/18398991
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
Globalcode – Open4education
Arquitetura do Passenger
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
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
Globalcode – Open4education
E qual o melhor app server?
Puma Passenger Unicorn
Globalcode – Open4education
Obrigado!
@wevtimoteo
@wevtimoteo
weverton.ct@gmail.com
• http://www.slideshare.net/wolcanus/como-definir-a-quantidade-de-workers-para-sua-aplicacao
• http://goo.gl/GTEGsg
Globalcode – Open4education
Referências
• Rack Documentation - http://rack.github.io/
• Server Architectures for Scalable Web - http://berb.github.io/diploma-thesis/original/042_serverarch.html
• The Philosophy Behind Unicorn - http://unicorn.bogomips.org/PHILOSOPHY.html
• Apache MPM prefork - http://httpd.apache.org/docs/current/mod/prefork.html
• How we've made Raptor up to 4x faster - http://www.rubyraptor.org/how-we-made-raptor-up-to-4x-faster-than-unicorn-and-up-to-2x-faster-than-puma-torquebox
Globalcode – Open4education
Mais referências
• Ruby App Server Arena - https://blog.engineyard.com/2014/ruby-app-server-arena-pt1
• Passenger Design and Architecture - https://www.phusionpassenger.com/documentation/Design%20and%20Architecture.html
• Rails Server Showdown - https://www.engineyard.com/articles/rails-server
• Slowloris - https://en.wikipedia.org/wiki/Slowloris_(software)
• RubyRaptor Optimizations - http://www.rubyraptor.org/pointer-tagging-linked-string-hash-tables-turbocaching-and-other-raptor-optimizations/