Nodejs - A performance que eu sempre quis ter

Post on 31-May-2015

7.147 views 8 download

description

Palestra apresentada no evento DevInSampa - www.devinsampa.com.br

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

Instalação

http://nodejs.org/#download

$ ./configure$ make$ make install

Desenvolvendo aplicações web

Express JS

http://expressjs.com/

Express JS

http://expressjs.com/

Sinatra ???

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#vows - http://vowsjs.org/

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 vows@0.4.6

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