Blog do Eduardo Costa Meu blog pessoal

31Out/110

Santa Ignorância, node.js!

Já faz um tempo que estou brincando com o node.js em casa e consegui uns números interessantes (800 requisições por segundo em uma t1.micro na Amazon). Pensei então: quanto atingiria um "hello world" na máquina i7 com oito cores que tenho no trabalho?

Vamos à experiência! O código é assombroso de tão simples:

var http = require("http");
http.createServer(function(request, response) {
    response.writeHead(200, { 'Content-Type': 'text/plain' });
    response.end("ok");
}).listen(8000);

Qualquer requisição feita na porta 8000 gera uma resposta "200" com o texto "ok". Vamos executar o "ab" (ApacheBench):

$ ab -n 10000 -c 100 http://localhost:8000/
This is ApacheBench, Version 2.3 <$Revision: 655654 $>
Copyright 1996 Adam Twiss, Zeus Technology Ltd, http://www.zeustech.net/
Licensed to The Apache Software Foundation, http://www.apache.org/
 
Benchmarking localhost (be patient)
Completed 1000 requests
Completed 2000 requests
Completed 3000 requests
Completed 4000 requests
Completed 5000 requests
Completed 6000 requests
Completed 7000 requests
Completed 8000 requests
Completed 9000 requests
Completed 10000 requests
Finished 10000 requests
 
Server Software:        
Server Hostname:        localhost
Server Port:            8000
 
Document Path:          /
Document Length:        2 bytes
 
Concurrency Level:      100
Time taken for tests:   0.736 seconds
Complete requests:      10000
Failed requests:        0
Write errors:           0
Total transferred:      660000 bytes
HTML transferred:       20000 bytes
Requests per second:    13587.64 [#/sec] (mean)
Time per request:       7.360 [ms] (mean)
Time per request:       0.074 [ms] (mean, across all concurrent requests)
Transfer rate:          875.77 [Kbytes/sec] received
 
Connection Times (ms)
              min  mean[+/-sd] median   max
Connect:        0    0   0.2      0       3
Processing:     1    7   3.5      7      19
Waiting:        1    7   3.5      7      19
Total:          2    7   3.4      7      19
 
Percentage of the requests served within a certain time (ms)
  50%      7
  66%      9
  75%     10
  80%     10
  90%     11
  95%     13
  98%     16
  99%     17
 100%     19 (longest request)

Repare na quantidade de requisições por segundo. Sim, IT'S OVER NINE THOUSAND! Só para comparar, fiz alguns Hello World's na mesma máquina:

  • Apache (instalação default do ubuntu) gerou 25 mil para o index.html!
  • Apache+PHP com um "echo ok" gerou 21 mil!
  • Apache+Perl gerou 3 mil
  • Rails no WEBrick (trocando o index dele pelo index.html do httpd do ubuntu) aguentou "apenas" 800 requisições por segundo (e ainda tomei alguns muitos "connection reset" no meio dos testes)

Eu pensei em testar com Java e Python também, mas Python está longe de meus conhecimentos para um Hello World "quick-and-dirt" e, em Java é impossível fazer um "index" em menos de cinco minutos sem ter o ambiente pré-pronto (ou seja, preciso instalar o Tomcat, criar um projeto no NB, criar um Servlet, etc etc).

E, antes de mandarem comentários xingando minha metodologia de testes, reparem que todos os exemplos são instalações "vanilla" sem nenhuma configuração. Eu achei os números do node.js interessantes e quis mostrar, comparando com outras tecnologias que permitem um "Hello World" saindo do forno em menos de 5 minutos.

No final, dá a impressão que o Apache é bem mais rápido que o node.js, porém o httpd usa N processos! O node.js, por outro lado, é 100% monothread (event-driven ao extremo) - por isso não escala legal em oito cores. Tentei procurar por uma solução multi-core para o node.js, mas sem sucesso (tanto o módulo "cluster" quanto o "multi-node" não funcionaram).

Mas, vamos ser sinceros: 13 mil requisições por segundo usando um único core é fora de escala! Em um ambiente como na Amazon, posso rapidamente fazer um cluster de nodes usando máquinas t1.micro ou m1.small e um ELB para balancear. E, a parte engraçada é: com 13 mil requisições por segundo, nem precisa de cluster! Isso praticamente aguenta um Twitter (a antiga versão Rails precisou segurar 11 mil)!

O node.js pode ser uma plataforma baixo-nível, mas, com as libraries corretas e frameworks "home made", é uma poderosa ferramenta para a web!