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