29
Definindo a quantidade de workers para sua app Weverton Timoteo hosted by supported by

Definindo a quantidade de workers para sua app

Embed Size (px)

Citation preview

Page 1: Definindo a quantidade de workers para sua app

Definindo a quantidade de workers para sua app!

Weverton Timoteohosted by supported by

Page 2: Definindo a quantidade de workers para sua app

Qual app server vocês utilizam?

Phusion PassengerUnicorn

Page 3: Definindo a quantidade de workers para sua app

Como funciona um webserver?

Web Server

Usuário

HTTP Request

HTTP Response

GET HTTP/1.1!!Accept: text/html!Accept-Encoding: gzip!Accept-Language: en-US!Connection: keep-alive!Host: www2.autocargo.com.br!User-Agent: Chrome/42.0.231

HTTP/1.x 200 OK!!Date: Sun, 10 May 2015 GMT!Server: nginx/1.4.6 (Ubuntu)!Cache-Control: max-age=0!Content-Type: text/html; charset=utf-8!X-Powered-By: Phusion Passenger 4.0.58

Page 4: Definindo a quantidade de workers para sua app

Fonte: rails-hosting.com - 2014

Qual web server mais utilizado?

• Apache 22.49%• Nginx 71.97%• Lighttpd 0.55%• IIS 0.08%• Puma 4.91%

Page 5: Definindo a quantidade de workers para sua app

Qual app server mais utilizado?

Fonte: rails-hosting.com - 2014

• Mongrel 3.94%• FastCGI 1.29%• Passenger 52.33%• Unicorn 59.57%• Rainbows! 0.72%• Puma 24.44%

Page 6: Definindo a quantidade de workers para sua app

Premissa:!Todos app servers implementam a interface Rack. Todas apps web respondem no formato do Rack.

Rack

Page 7: Definindo a quantidade de workers para sua app

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)

Page 8: Definindo a quantidade de workers para sua app

Rack Handlers

• Ebb

• Fuzed

• Glassfish v3

• Phusion Passenger • Puma

• Reel

• Unicorn • unixrack

• uWSGI

• yahns

Page 9: Definindo a quantidade de workers para sua app

Web frameworks suportados• Camping!• Coset!• Espresso!• Halcyon!• Mack!• Maveric!• Merb!• etc

• Racktools::SimpleApplication!• Ramaze!• Ruby on Rails!• Rum!• Sinatra!• Sin!• Vintage!• Wee

Page 10: Definindo a quantidade de workers para sua app

Qual app server escolher?

Phusion PassengerUnicorn

Page 11: Definindo a quantidade de workers para sua app

• MultiProcess Blocking • MultiThreading Blocking • Evented

Modelos de I/O

Page 12: Definindo a quantidade de workers para sua app

• 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

Page 13: Definindo a quantidade de workers para sua app

• 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

Page 14: Definindo a quantidade de workers para sua app

• 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

Page 15: Definindo a quantidade de workers para sua app

• 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

Page 16: Definindo a quantidade de workers para sua app

Processo 1 Processo 2 Processo 3 Processo N

Slow Client

Client

Slow Client

Slow Client

Slow Client

Client

Fila de requisições!

Slow clients?

Page 17: Definindo a quantidade de workers para sua app

• 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áticosuserspace:!Todo código que roda fora da área de memória virtual das tarefas do Kernel

Reverse Proxying

Page 18: Definindo a quantidade de workers para sua app

• 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!

Page 19: Definindo a quantidade de workers para sua app

!gem 'derailed', group: :development

$ cat << EOF > perf.rake require 'bundler' Bundler.setup! require 'derailed_benchmarks' require 'derailed_benchmarks/tasks'EOF

Medindo consumo de recursos

Ruby 2.0+ e Rails 3.2+

Page 20: Definindo a quantidade de workers para sua app

Medindo consumo de recursos

Page 21: Definindo a quantidade de workers para sua app

Quantos workers devo utilizar no Unicorn?

Quanto mais requests, mais worker_processes

Quanto mais worker_processes, mais mem. RAM

Copyright DigitalOcean

Memory leak?

Page 22: Definindo a quantidade de workers para sua app

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

Unicorn Killer

Page 23: Definindo a quantidade de workers para sua app

• Inspirado no Mongrel • Suporta “verdadeiro paralelismo” • Funciona muito bem com Rubinius e JRuby • Evented I/O • Thread Pool • Clustered Mode

Puma

Page 24: Definindo a quantidade de workers para sua app

• 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)

Page 25: Definindo a quantidade de workers para sua app

• 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?

Page 26: Definindo a quantidade de workers para sua app

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

Page 27: Definindo a quantidade de workers para sua app

Obrigado!

@wevtimoteo

[email protected]

http://www.slideshare.net/wevtimoteo/definindo-a-quantidade-de-workers-para-sua-app

http://goo.gl/uCl1L4

Page 28: Definindo a quantidade de workers para sua app

• 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

Referências

Page 29: Definindo a quantidade de workers para sua app

• 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/

Referências