2. When to use Node and when not to
• Don't use node to server static files - there are
better and easier [to configure] servers than node
(NGINX, varnish, HAProxy)
• Don't use node for simple CRUD apps - you will
have to build it all yourself
• You have to build almost everything yourself -
great for APIs
– Great for iterative development
• Use it for real-time
– Node is responding to requests super fast
3. What do you need to start
• Node (http://nodejs.org/)
– brew install node or download via URL
• nvm (https://github.com/creationix/nvm/)
– nvm install v0.7.1
• npm (http://npmjs.org/)
– we have our NYT repo
• online docs and tutorials, READMEs
• your favorite text editor
• node whatever.js
– node compiles your code before every invocation
6. Middleware
1 function loadUser(req, res, next) {
2 // You would fetch your user from the db
3 var user = users[req.params.id];
4 if (user) {
5 req.user = user;
6 next();
7 } else {
8 next(new Error('Failed to load user ' + req.params.id));
9 }
10 }
11
12 app.get('/user/:id', loadUser, function(req, res){
13 res.send('Viewing user ' + req.user.name);
14 });
12. General
• Uncaught Exception kills the server
– Log errors using process.on('uncaugtException')
– deamontools supervise, monit
• Logging
– Winston (https://github.com/flatiron/winston/)
• Use ab for testing
– sudo sysctl -w net.inet.tcp.msl=300
– Demo (ex3)
13. Concurrency model
• Non-blocking IO
– Uses epoll, kqueue, select
• Single-threaded event-loop (uses libev and libeio)
– As oppose to thread per request
– less context-switching, less CPU usage, less memory
• The event loop is not intended to make
computationally intensive tasks responsive, it’s meant
to cut the resource waste related to waiting for I/O
by Mikito Takada
• Long synchronous code WILL BLOCK ALL OTHERS
– Extract heavy code to its own service or process
– Use WebWorkers to spawn a “process”
15. Maximizing the server
• Single thread running on a single CPU
• Use cluster to take all CPUs
1 var cluster = require('cluster');
2 var http = require('http');
3 var numCPUs = require('os').cpus().length;
4
5 if (cluster.isMaster) {
6 // Fork workers.
7 for (var i = 0; i < numCPUs; i++) {
8 cluster.fork();
9 }
10 } else {
11 // Workers can share any TCP connection
12 // In this case its a HTTP server
13 http.createServer(function(req, res) {
14 res.writeHead(200);
15 res.end("hello worldn");
16 }).listen(8000);
17 }
16. Sharing between instances
• As you spawn multiple instances, you need to
share data (=memory)
• You can use IPC
• You can use DB
• Or, you can use in-memory cache
– memcached
• Strings, integers, anything else is serialized
• Set, get, delete, replace, append, prepend
• Expiry
– redis
19. redis
• Blazingly fast, in-memory cache
– Size limited to memory
– Good for ephemeral data (cache, session), for
syncing servers
• Can be saved to disk, mostly for faster start up
• Use async/Q for handling multiple requests
• Supports expiry, pub-sub, transactions, server-
side LUA scripts
• connect-redis for automatic session sync