Jak używać Node.klastry js z moją prostą aplikacją Express?

- zbudowałem prostą aplikację, która pobiera dane (50 pozycji) z Redis DB i wyrzuca je do localhost. Zrobiłem ApacheBench (c = 100, n = 50000) i dostaję pół przyzwoity 150 żądań / s na dwurdzeniowym t2080 @ 1.73 GHz (mój laptop 6 y.o), ale użycie proc jest bardzo rozczarowujące, jak pokazano: Tutaj wpisz opis obrazka

Tylko jeden rdzeń jest używany, co jest zgodne z projektem w Node, ale myślę, że mogę prawie podwoić moje żądania / SEK do ~300, może nawet więcej, jeśli mogę użyć Node.klastry js. Bawiłem się całkiem trochę, ale nie byłem w stanie dowiedzieć się, jak umieścić kod podany tutaj do użytku z moją aplikacją, która jest wymieniona poniżej:

var 
    express = require( 'express' ),
    app     = express.createServer(),
    redis   = require( 'redis' ).createClient();

app.configure( function() {
    app.set( 'view options', { layout: false } );
    app.set( 'view engine', 'jade' );
    app.set( 'views', __dirname + '/views' );
    app.use( express.bodyParser() );
} );

function log( what ) { console.log( what ); }

app.get( '/', function( req, res ) {
    redis.lrange( 'items', 0, 50, function( err, items ) {
            if( err ) { log( err ); } else {
                res.render( 'index', { items: items } );
            }
    });
});

app.listen( 8080 );

Chcę również podkreślić, że aplikacja jest intensywne I / o (nie CPU-intensive, co uczyniłoby coś w rodzaju threads-a-gogo lepszym Wyborem niż klastry).

Chciałbym pomóc w rozwiązaniu tego problemu.
Author: vjk2005, 2012-05-19

1 answers

W rzeczywistości twoje obciążenie nie jest tak naprawdę związane z I / O: jest związane z procesorem ze względu na koszt dynamicznego generowania stron opartych na jade. Nie mogę odgadnąć złożoności Twojego szablonu jade, ale nawet przy prostych szablonach generowanie stron HTML jest drogie.

Do moich testów użyłem tego szablonu:

html(lang="en")
  head
    title Example
  body
    h1 Jade - node template engine
    #container
      ul#users
        each user in items
          li User:#{user}

Dodałem 100 atrapy ciągów do klucza items w Redis.

Na moim pudełku dostaję 475 req / s z node.procesor JS na 100% (co oznacza 50% zużycie procesora na tym dwurdzeniowym pudełku). Let ' s "replace": {]}
res.render( 'index', { items: items } );

By:

res.send( '<html lang="en"><head><title>Example</title></head><body><h1>Jade - node template engine</h1><div id="container"><ul id="users"><li>User:NOTHING</li><li>User:NOTHING</li><li>User:NOTHING</li><li>User:NOTHING</li><li>User:NOTHING</li><li>User:NOTHING</li><li>User:NOTHING</li><li>User:NOTHING</li><li>User:NOTHING</li><li>User:NOTHING</li><li>User:NOTHING</li><li>User:NOTHING</li><li>User:NOTHING</li><li>User:NOTHING</li><li>User:NOTHING</li><li>User:NOTHING</li><li>User:NOTHING</li><li>User:NOTHING</li><li>User:NOTHING</li><li>User:NOTHING</li><li>User:NOTHING</li><li>User:NOTHING</li><li>User:NOTHING</li><li>User:NOTHING</li><li>User:NOTHING</li><li>User:NOTHING</li><li>User:NOTHING</li><li>User:NOTHING</li><li>User:NOTHING</li><li>User:NOTHING</li><li>User:NOTHING</li><li>User:NOTHING</li><li>User:NOTHING</li><li>User:NOTHING</li><li>User:NOTHING</li><li>User:NOTHING</li><li>User:NOTHING</li><li>User:NOTHING</li><li>User:NOTHING</li><li>User:NOTHING</li><li>User:NOTHING</li><li>User:NOTHING</li><li>User:NOTHING</li><li>User:NOTHING</li><li>User:NOTHING</li><li>User:NOTHING</li><li>User:NOTHING</li><li>User:NOTHING</li><li>User:NOTHING</li><li>User:NOTHING</li><li>User:NOTHING</li></ul></div></body></html>' );

Teraz wynik benchmarka jest bliski 2700 req / s. więc wąskie gardło jest wyraźnie spowodowane formatowaniem strony HTML.

Używanie pakietu klastrowego w tej sytuacji jest dobrym pomysłem i jest proste. Kod można modyfikować w następujący sposób:

var cluster = require('cluster')

if ( cluster.isMaster ) {
  for ( var i=0; i<2; ++i )
    cluster.fork();
} else {
  var
      express = require( 'express' ),
      app     = express.createServer(),
      redis   = require( 'redis' ).createClient();

  app.configure( function() {
      app.set( 'view options', { layout: false } );
      app.set( 'view engine', 'jade' );
      app.set( 'views', __dirname + '/views' );
      app.use( express.bodyParser() );
  });

  function log( what ) { console.log( what ); }

  app.get( '/', function( req, res ) {
      redis.lrange( 'items', 0, 50, function( err, items ) {
            if( err ) { log( err ); } else {
              res.render( 'index', { items: items } );
            }
      });
  });

  app.listen( 8080 );
}

Teraz wynik benchmarka jest bliski 750 req/s przy 100% zużyciu procesora (w porównaniu z początkowymi 475 req / s).

 34
Author: Didier Spezia,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2012-05-19 11:49:48