
The advantages of Node.js for writing massively scalable servers are manifold. I’d like to share with you the advantages I think are most important: the ease of which you can write asynchronous server logic, the ability to write easily scalable servers, and the ability to write your app 100% in JavaScript.
I wrote a couple blog articles as an introduction to using JavaScript for each tier of an app’s stack: Why Full Stack javascript Rocks! (part 1) • Why FullStack JavaScript Rocks! (part 2)
Asynchronous I/O
Node.js makes it simple to write asynchronous I/O employing an architecture based on callbacks, promises, and/or events.
Blocking I/O is to be avoided. To put it simply, it breaks Node’s concurrency model to use blocking I/O. Blocking I/O can kill your ability to scale Node.js clusters.
The advantage of asynchronous I/O is that you never have to really worry about writing concurrent code. All your app/server code is executed in a single thread, and instead of dealing with the pain of multi-threading, one simply spins up stateless Node.js worker drones on each core, or distributed in a virtual server farm. Node.js makes writing scalable, concurrently-executing server farms easy!
Heavy Computation
Google’s V8 engine, which Node uses to execute JavaScript, is by no means slow, but long, blocking calculations could be a limitation for certain computationally intensive apps and servers.
Most Node.js code is incredibly lean, and day-to-day coding of a massively scalable app does not require any intense computation. Examples of intense computation would be encryption (check out the built-in `crypto` library), machine learning, or rendering video.
Even though these are approaches of last resort, and rarely needed, I would like to mention a few for completeness:
One might, for example, implement a clustered Java server with a REST API that interfaces with the NLP Toolkit. Your node servers would just need to communicate with them via REST. Not too difficult.
Maybe just offload that stuff to Hadoop or SOLR.
Or you might evaluate if `node-cuda` fits into your project so you can offload calculation to GPUs asynchronously.
Node is extensible via C++ plugins, so you have access close to the metal in the rare case you would need it. You can also asynchronously interface with UNIX sockets.
server.listen('/tmp/echo.sock', function() { ... });
MongoDB
For most situations MongoDB is the scalable data storage/compute farm of choice. And awesomely, you write queries for it with 100% JavaScript.
Really, most people haven’t been writing raw SQL for years, in any maintainable way. It’s great for one-off scripts, etc., but usually a framework such as Hibernate, NHibernate, etc. is employed to abstract much of the repetitive aspects of accessing data. (There are often times multiple data access abstraction libraries for each programming language.)
MongoDB moves most of this logic to the database, so only a thin ORM (or ODM) is needed. Mongoose ODM is a handy, thin wrapper to MongoDB for Node.js.
Mongo stores data in a JSON-like binary format, can be retrieved with JSON and JavaScript queries, supports MapReduce, and has clustered storage and redundancy built in.
Need to scale Mongo? Just spin up another replica set. Or take the easy route and use a hosted MongoDB service such as MongoHQ. Nodejitsu has built-in support for easily creating and interfacing with Mongo (and Redis) instances in the cloud.
function finishReading (callback) {
var query = mongoose.models['article'].findOneAndUpdate(
{
title: 'The Advantages of Full Stack JavaScript: Node.js, I/O, Data, and Computation'
},
{
$push: { readers: 'you' }
},
{
upsert: true,
}
);
query.exec(callback);
}
Welcome to massively scalable 100% JavaScript.
Cheers,
William