An Introduction to Node.js
Introduction
Node.js is an evented I/O server built on Google’s V8 JavaScript engine. Node provides a simple way to build highly scalable server applications. This article will provide an introduction to Node along with installation details and a first server.
Doctor’s Office Reception Lines
Traditional servers are thread based. Each connection gets a new thread which is held (along with memory and other resources) for as long as it takes to service the request. An event driven server replaces that model with an I/O event queue. Each connection that comes in goes into an event queue and fires a callback function for that event. Each connection uses only a small amount of memory.
Tim Caswell and Dan York use the a doctor’s office reception line as an analogy to describe the difference between threaded and asynchronous systems. A traditional threaded model in a reception line would have you stand at the receptionist for as long as it takes you to complete your transaction. Even if you have multiple forms to fill out, you would stay at the window until they are all filled out. The only way to scale is to add more receptionists.
In an event based system, the receptionist gives you the forms with a clipboard and pen and tells you to come back when you are done. The receptionist can then help the next person in line. When your forms are done, you get back in line. This system is already scalable. If the line gets to long, you can add more receptionists, but not at the rate you would need to in the “threaded” version.
As an example of the performance gains this model can provide, LinkedIn recently switched from Rails to Node.js when they overhauled their mobile application. Here are the results:
“…Node showed us huge performance gains compared to what we were using before, which was Ruby on Rails.” The improvements the team saw were staggering. They went from running 15 servers with 15 instances (virtual servers) on each physical machine, to just four instances that can handle double the traffic. The capacity estimate is based on load testing the team has done.
JavaScript?
Why choose JavaScript as the language? Isn’t JavaScript an abomination? It turns out that JavaScript has a number of advantages for an asynchronous server:
- There are no existing I/O libraries for JavaScript, so there is no blocking I/O libraries to lock up the server. This is an issue with evented I/O libraries in other languages such as Ruby’s EventMachine and Python’s Twisted.
- Most JavaScript is written in a browser. The language is built to support the asynchronous environment in the browser, so it fits well in an asynchronous server.
- There is a large base of JavaScript programmers who have been writing JavaScript on the client. These programmers can use that knowledge writing server applications.
Installing Node.js
Node.js installs out of the box on Linux, Max and Solaris. To build Node.js on one of these platforms, do the following:
- git clone git://github.com/joyent/node.git
- cd node
- ./configure
- sudo make install
There is a Mac binary and an experimental Windows executable available.
The Command Line Interface
Running node without any parameters will start a command line interface that allows you to run JavaScript code. You will see a “>” prompt and can start entering JavaScript. The following commands are available:
- .help: returns a list of commands
- .break: when you are entering a multi-line statement, .break allows you to break out and start over
- .clear: clears the local context
- .exit: exits the REPL
- _: contains the results of the last expression
Hello World
No introductory article on a new technology is complete without a hello world program. Our hello world program will create a simple web server that returns a response of “Hello World”.
Node.js implements the CommonJS specification for it’s built in modules. To create our web server, we first need to import the HTTP module using the require method:
var http = require(‘http’);
The HTTP module contains a createServer method that will create an http server for us. This method takes a callback function that takes a request and response parameter. This callback function will be called for each connection that is made to our server.
var server = http.createServer(function (request, response) { … });
To send our “hello world” back to the client, we use the response object we received in the callback. The writeHead method allows us to set the status code and content-type. We can then use the end method to send the text end close the response.
response.writeHead(200, { ‘Content-Type’ : ‘text/html’ });
response.end(‘Hello World!’);
Last, we tell our server to listen on a port number:
server.listen(7000);
The full program now looks like this:
var http = require('http');
var server = http.createServer(function(request, response) {
response.writeHead(200, { 'Content-Type' : 'text/html' });
response.end('Hello World!');
});
server.listen(7000);
console.log('Server listening on port 7000');
We save this to server.js and run “node server.js” on the command line to start our server. You can now navigate to “http://localhost:7000” to see the output of your program.
Conclusion
Node.js is an exciting new technology that makes it simple to build scalable servers. If you have requirement for a high volume server that will be I/O bound, you should consider it as an alternative to the thread based servers that are common today.
is there any alternate for Node.js for those not using Google App Engine?
I don’t believe you can host node apps on Google App Engine. There is a list of hosting options for Node.js at https://github.com/joyent/node/wiki/hosting.