Beyond With
#whoami
#ruby
I Ruby
class Product < ActiveRecord::Base after_create :set_initial_inventory has_many :variants, :dependent => :destroy has_many :images, :as => :viewable, :order => :position, :dependent => :destroy has_many :properties, :through => :product_properties belongs_to :tax_category validates_presence_of :name validates_presence_of :master_price validates_presence_of :description make_permalink :with => :name, :field => :permalink end Model Friday, August 7, 2009
“Tornar as coisas simples fáceis e as coisas difíceis possíveis” Fisolofia Ruby
Código Bonito
Código Bonito Don’t RepeatYourself
Código Bonito Don’t RepeatYourself Convention Over Configuration
class Booking < ActiveRecord::Base belongs_to :hotel belongs_to :user validates_presence_of :hotel validates_presence_of :user validates_presence_of :credit_card validates_presence_of :credit_card_name validates_length_of :credit_card, :within => 16..16 validates_format_of :credit_card, :with => /^d*$/ validates_length_of :credit_card_name, :within => 3..70 def total hotel.price * nights end def nights ((checkout_date - checkin_date) / 1.day).round end def to_s "Booking(#{user},#{hotel})" end end
#números
2010
~ 2 bilhões de usuários de internet em todo mundo
68 milhões de usuários
68 milhões de usuários 37 milhões são ativos
0 22,5 45 67,5 90 Brasil Italia Espanha Japão EUA Inglaterra França AustráliaAlemanha Suiça 59 % 63 % 72 %73 %74 %74 %75 % 77 %78 % 86 % % de usuários ativos nas Redes Sociais Fonte:The Nielsen Company
2014
~ 70% dos adultos serão usuários regulares de redes sociais
Estrutura física de servidores para escalar
Escalando na vertical
Escalando na vertical
Escalando na horizontal
Escalando na horizontal
Escalando na horizontal
Escalando na horizontal
Escalando DB na horizontal write read write write read
Escalando DB na horizontal Shard Database Shard Database Shard Database Shard Database Shard Database Shard Database
Arquitetura pra fazer o software escalar
Pattern para atender muitos requests
Pattern para atender muitos requests Finalize a requisição o mais rápido possível
HTTP GET
HTTP POST
Por que então mais uma tecnologia ?
Escalando na horizontal
Escalando na horizontal
Evented, non-blocking I/O GoogleV8 Engine
Qual é o problema das tecnologias atuais ?
Como manter conectados 10, 20 ou 30 mil usuários simultâneos ?
Nosso código costuma ser escrito assim
Nosso código costuma ser escrito assim O que o software está fazendo enquanto a querie executa ?
Na maioria dos casos está travado esperando a resposta
Ruby on Rails HTTPD Database
Ruby on Rails HTTPD Database
Ruby on Rails HTTPD Database
Ruby on Rails HTTPD RUBY PROCESS Database
Ruby on Rails HTTPD RUBY PROCESS Database BLOCK
Ruby on Rails HTTPD RUBY PROCESS RUBY PROCESS RUBY PROCESS EUBY PROCESS Database BLOCK BLOCK BLOCK BLOCK
Java HTTPD Database Servlet Container Servlet
Java HTTPD Database Servlet Container Servlet
Java HTTPD Database Servlet Container Servlet
Java HTTPD Database Servlet Container Thread Servlet
Java HTTPD Database Servlet Container Thread Servlet BLOCK
Java HTTPD Database Servlet Container Thread Thread Thread Thread Thread Thread Thread Servlet BLOCK BLOCK BLOCK BLOCK BLOCK BLOCK BLOCK
Apenas um processo abrindo uma thread para cada request
Produtividade do programador mais que performance da tecnologia
Java Rumble ?!? :p
Apenas um processo abrindo uma thread para cada request
Parece bom mas ...
Como manter conectados 10, 20 ou 30 mil usuários simultâneos ?
Como manter conectados 10, 20 ou 30 mil usuários simultâneos ? 30 mil threads ?
Apache vs NGINX concurrency × reqs/sec http://blog.webfaction.com/a-little-holiday-present concurrency × reqs/sec http://blog.webfaction.com/a-little-holiday-present
Apache vs NGINX concurrency × memory http://blog.webfaction.com/a-little-holiday-present concurrency × reqs/sec http://blog.webfaction.com/a-little-holiday-present
Apache cria uma thread por request
Troca de contexto entre theads tem um custo
Cada OS Thread cria uma pilha de execução nova
Pense bem antes de usar uma thread por request quando precisar suportar alta concorrência
Pattern para atender muitos requests Finalize a requisição o mais rápido possível
Pattern para atender alta concorrência
Pattern para atender alta concorrência Evite threads
Pattern para atender alta concorrência Evite threads Use um Event Loop
Performance != Escalabilidade
Performance != Escalabilidade mas ...
Uma performance melhor ajuda a escalar com menos recursos
Precisamos fazer I/O de outra maneira
Latência de I/O
L1 3 ciclos Latência de I/O
L1 3 ciclos L2 14 ciclos Latência de I/O
L1 3 ciclos L2 14 ciclos RAM 250 ciclos Latência de I/O
L1 3 ciclos L2 14 ciclos RAM 250 ciclos Disco 41.000.000 ciclos Latência de I/O
L1 3 ciclos L2 14 ciclos RAM 250 ciclos Disco 41.000.000 ciclos Rede 240.000.000 ciclos Latência de I/O
L1 3 ciclos L2 14 ciclos RAM 250 ciclos Disco 41.000.000 ciclos Rede 240.000.000 ciclos Latência de I/O
I/O não bloqueante
L1 3 ciclos L2 14 ciclos RAM 250 ciclos I/O não bloqueante
L1 3 ciclos L2 14 ciclos RAM 250 ciclos I/O não bloqueante I/O bloqueante
L1 3 ciclos L2 14 ciclos RAM 250 ciclos Disco 41.000.000 ciclos Rede 240.000.000 ciclos I/O não bloqueante I/O bloqueante
Infraestrutura não bloqueante, puramente baseada em eventos, para desenvolver software de alta concorrência
Servidor TCP simples em NodeJS O código acima faz com que a execução retorne imediatamente ao event loop
Por que já não faziamos dessa forma ?
POSIX Assync I/O não suportado por todos os S.Os
POSIX Assync I/O não suportado por todos os S.Os libmysql_client não permite query async
Filosofia do NodeJS
Filosofia do NodeJS Todo I/O deveria ser feito desta forma
Arquitetura event loop (libev) thread pool (libeio) V8 Node Bindings Node standard libraryJavascript C
#reactor
ev_loop() Pilha de execução I/O em disco (bloqueante)
ev_loop() socket_readdable(1) Pilha de execução I/O em disco (bloqueante)
ev_loop() socket_readdable(1) http_parse(1) Pilha de execução I/O em disco (bloqueante)
ev_loop() socket_readdable(1) http_parse(1) Pilha de execução load(“index.html”) I/O em disco (bloqueante)
ev_loop() socket_readdable(1) http_parse(1) Pilha de execução I/O em disco (bloqueante)
ev_loop() socket_readdable(1) Pilha de execução I/O em disco (bloqueante)
ev_loop() Pilha de execução I/O em disco (bloqueante)
ev_loop() Pilha de execução I/O em RAM (não bloqueante)
ev_loop() socket_readdable(2) Pilha de execução I/O em RAM (não bloqueante)
ev_loop() socket_readdable(2) http_parse(2) Pilha de execução I/O em RAM (não bloqueante)
ev_loop() socket_readdable(2) http_parse(2) Pilha de execução http_respond(2) I/O em RAM (não bloqueante)
ev_loop() socket_readdable(2) http_parse(2) Pilha de execução I/O em RAM (não bloqueante)
ev_loop() socket_readdable(2) Pilha de execução I/O em RAM (não bloqueante)
ev_loop() Pilha de execução I/O em RAM (não bloqueante)
ev_loop() Pilha de execução Arquivo carregou do disco
ev_loop() file_loaded() Pilha de execução Arquivo carregou do disco
ev_loop() file_loaded() http_respond(1) Pilha de execução Arquivo carregou do disco
ev_loop() file_loaded() Pilha de execução Arquivo carregou do disco
ev_loop() Pilha de execução Arquivo carregou do disco
Arquitetura Web
Arquitetura Web Nginx
Arquitetura Web Ruby on Rails Ruby on Rails Ruby on Rails Ruby on Rails Ruby on Rails Nginx
Arquitetura Web Ruby on Rails Ruby on Rails Ruby on Rails Ruby on Rails Ruby on Rails Nginx NodeJS
Arquitetura Web Nginx
#bizarrices
Isso é bonito?
em-syslog
em-spec em-dns em-syslog
em-proxy em-spec em-dns em-syslog em-ruby-irc em-memcache-client
em-mysql em-proxy em-syncrony em-spec em-dns em-syslog em-ruby-irc em-mongo em-memcache-client em-simplechat
em-mysql em-http-request em-websocket em-proxy em-syncrony em-redis em-spec em-ftpd em-dns em-jabberbot em-resolv-replace em-syslog em-dir-watcher em-ruby-irc em-net-http em-s3 em-mongo em-memcache-client em-simplechat
EM-*
WS-*
#simplicidade
Código bloqueante
Código bloqueante Código não-bloqueante
Callback
Callback Callback
#evolução
Don’t RepeatYourself
XML Properties YAML Configurações
XML Properties YAML Configurações JSON Transporte
Configurações JSON
Configurações JSON
Configurações JSON Transporte
Configurações Javascript Object Notation Transporte
Java Ruby Python Server Side PHP
Java Ruby Python Server Side PHP Client Side JavaScript
Server Side JavaScript
Server Side JavaScript
Server Side JavaScript Client Side
#ecossistema
Sinatra detected !
TDD / BDD
TDD / BDD #http://github.com/visionmedia/expresso/
TDD / BDD #vows - http://vowsjs.org/
#last-thing
on
Client Ruby on Rails
Client Ruby on Rails
Servidor em Node.js
Servidor em Node.js
Código Client-Side ( JS )
Código Client-Side ( JS )
Código Server Coffeescript
#conclusão
I Ruby
Obrigado !!! Emerson Macedo @emerleite http://nodecasts.org http://codificando.com
Referências http://www.internetworldstats.com/emarketing.htm http://en.wikipedia.org/wiki/Event_loop http://lse.sourceforge.net/io/aio.html http://code.google.com/p/v8/ http://opengroup.org/onlinepubs/007908775/xsh/select.html http://en.wikipedia.org/wiki/Thread_pool_pattern http://www.commonjs.org/specs/modules/1.0/ http://en.wikipedia.org/wiki/File_descriptor http://en.wikipedia.org/wiki/Reactor_pattern

Beyond Ruby with NodeJS - RubyConf Brasil 2010