Nodejs - A performance que eu sempre quis ter
-
Upload
emerson-macedo -
Category
Technology
-
view
7.147 -
download
8
description
Transcript of Nodejs - A performance que eu sempre quis ter
A performance que eu sempre quis ter
Emerson Macedo@emerleite
http://codificando.comhttp://visaoagil.wordpress.com/author/emerleite/
#whoami
2000
360 milhões de usuários de internet
em todo mundo
9,8 milhões de usuários
9,8 milhões de usuários
4,8 milhões são ativos
Com poucos usuários qualquer tecnologia
funciona
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
Com muitos usuários nem toda tecnologia
funciona
Tecnologias atuais
Todas essas tecnologias tem algo em comum
PHP 1995
PHP 1995
Java EE 1998
PHP 1995
Java EE 1998
ASP.Net 2002
PHP 1995
Java EE 1998
ASP.Net 2002
Ruby on Rails 2005
PHP 1995
Java EE 1998
ASP.Net 2002
Ruby on Rails 2005
Django 2005
Por que então mais uma tecnologia ?
0
500
1000
1500
2000
2000 2010
2.000 milhões
360 milhões
Usuários de Internet no Mundo (em milhões)
0
17,5
35
52,5
70
2000 2010
70 milhões
10 milhões
Usuários de Internet no Brasil (em milhões)
Mas já escalamos muito bem nossos sites
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
ShardDatabase
ShardDatabase
ShardDatabase
ShardDatabase
ShardDatabase
ShardDatabase
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
Pattern para atender muitos requests
Finalize a requisição o mais rápido possível
Por que então mais uma tecnologia ?
2014
~ 70% dos adultos serão usuários regulares de redes sociais
Como manter conectados 10, 20 ou
30 mil usuários simultâneos ?
Escalando na horizontal
Escalando na horizontal
Evented, non-blocking I/O Google V8 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
Rails ou Django
HTTPD Database
Rails ou Django
HTTPD Database
Rails ou Django
HTTPD Database
Rails ou Django
HTTPD
RUNTIMEPROCESS
Database
Rails ou Django
HTTPD
RUNTIMEPROCESS
Database
BLOCK
Rails ou Django
HTTPD
RUNTIMEPROCESS
RUNTIMEPROCESS
RUNTIMEPROCESS
RUNTIMEPROCESS
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 ContainerThread
Servlet
Java
HTTPD Database
Servlet ContainerThread
Servlet
BLOCK
Java
HTTPD Database
Servlet ContainerThread
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
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 NGINXconcurrency × reqs/sec
http://blog.webfaction.com/a-little-holiday-present
Apache vs NGINXconcurrency × reqs/sec
http://blog.webfaction.com/a-little-holiday-present
Apache vs NGINXconcurrency × memory
http://blog.webfaction.com/a-little-holiday-present
Apache vs NGINXconcurrency × 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
Não devemos usar uma thread por request
quando precisamos suportar alta concorrência
Como manter conectados 10, 20 ou
30 mil usuários simultâneos ?
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
Não crie threads
Pattern para atender alta concorrência
Não crie threads
Use um Event Loop
Produtividade do programador mais que
performance da tecnologia
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
Para qualquer operação que acesse o disco ou a rede deve existir um callback
Arquitetura
eventloop
(libev)
threadpool
(libeio)
V8
Node Bindings
Node standard libraryJavascript
C
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
Rubyor
Python
Rubyor
Python
Rubyor
Python
Rubyor
Python
Rubyor
Python
Nginx
Arquitetura Web
Rubyor
Python
Rubyor
Python
Rubyor
Python
Rubyor
Python
Rubyor
Python
Nginx
NodeJS
Arquitetura Web
Nginx
Arquitetura Web
Nginx
NodeJS
Arquitetura Web
NodeJS
Arquitetura Web
NodeJS
Quando NodeJS estiver bem maduro, a idéia de Ryan é que ele seja a porta de
entrada. Será ?
Por que Javascript ?
Não é burocrático,assim como Ruby ou
Python
Não é burocrático,assim como Ruby ou
Python
Especialistas Javascript Client-Sidejá pensam assíncrono
Instalação
Instalação
http://nodejs.org/#download
$ ./configure$ make$ make install
Desenvolvendo aplicações web
Express JS#múltiplos ambientes
Express JS#markup
Express JS#markup
Express JS#stylesheet
Express JS#comportamento
Express JS#comportamento
Database
Database
http://wiki.github.com/ry/node/modules#database
Database
http://wiki.github.com/ry/node/modules#database
MongoDBCouchDBMySQL AssíncronoSqliteRedisPostgres
Test driven development
Test driven development#http://github.com/visionmedia/expresso/
Node package manager
http://github.com/isaacs/npm
Node package manager
http://github.com/isaacs/npm
#instalação$ curl http://npmjs.org/install.sh | sh
Node package manager
http://github.com/isaacs/npm
#instalação$ curl http://npmjs.org/install.sh | sh
#utilização$ npm install pacote
Node package manager
http://github.com/isaacs/npm
#instalação$ curl http://npmjs.org/install.sh | sh
#desinstalação$ npm uninstall npm
#utilização$ npm install pacote
Node package manager
http://github.com/isaacs/npm
#stable - expressjs$ npm install express
Node package manager
http://github.com/isaacs/npm
#stable - expressjs$ npm install express
Node package manager
http://github.com/isaacs/npm
#unstable - hamljs$ npm install hamljs@latest
#stable - expressjs$ npm install express
Node package manager
http://github.com/isaacs/npm
#unstable - hamljs$ npm install hamljs@latest
#versão - vows$ npm install [email protected]
Node package manager
Node package manager
http://github.com/isaacs/npm
#listando$ npm list
Node package manager
http://github.com/isaacs/npm
#listando$ npm list
Node package manager
http://github.com/isaacs/npm
#instalado$ npm list @installed
#listando$ npm list
Node package manager
http://github.com/isaacs/npm
#instalado$ npm list @installed
#autor$ npm list =ry
Node package manager
Node package manager
http://github.com/isaacs/npm
#atualizando$ npm update
Node package manager
http://github.com/isaacs/npm
#atualizando$ npm update
Node package manager
http://github.com/isaacs/npm
#porpacote$ npm update pacote
#atualizando$ npm update
Node package manager
http://github.com/isaacs/npm
#porpacote$ npm update pacote
#ondefica~/.node_libraries
Deployment em produção
Spark + Nginx
http://github.com/senchalabs/spark
Spark + Nginx
http://github.com/senchalabs/spark
#instalação$ npm install spark@latest
Spark + Nginx
http://github.com/senchalabs/spark
#instalação$ npm install spark@latest
#utilização$ spark -p [port] -n [processes]
Spark + Nginx
Spark + Nginx#config.js
Spark + Nginx#config.js
#nginx
Oportunidades
Upload de arquivos
Upload de arquivos
Streaming de vídeo
Upload de arquivos
Streaming de vídeo
Real-time web applications
Alternativas
Status atual
Status atual
Versão 0.1.103
Javascript ~ 6000 linhas
Status atual
Versão 0.1.103
Javascript ~ 6000 linhas
C++ ~ 11000 linhas
Status atual
Versão 0.1.103
Javascript ~ 6000 linhas
C++ ~ 11000 linhas
Mailin list ~ 1200 pessoas
Status atual
Versão 0.1.103
Javascript ~ 6000 linhas
C++ ~ 11000 linhas
Mailin list ~ 1200 pessoas
Status atual
Versão 0.1.103
Contribuidores ~ 70 pessoas
Conclusão
I/O não deve ser feito da forma que fazemos
hoje em dia
Muito promissor
Muito promissor
Podemos usar já !!!
Produtividade do programador mais que
performance da tecnologia
Obrigado !!!
Emerson Macedo@emerleite
http://codificando.com
Referênciashttp://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