Saturday, September 24, 2011 at 11:29PM Node.js Showdown
In this technical article Stefan Schneider-Kennedy takes a closer look at Node.js.
I’ve been interested in looking at Node.js for some time. I was intrigued by the concept of the “evented” web server and I also quite like the JavaScript language. As best I can tell, these tools are what make Node.js “cool” and they’ve inspired me to take a closer look at this framework today.
First up: the “event driven” concept. Traditional web servers spawn a new thread for each client request, which is a fairly heavyweighted way of handling most requests. For example, in a database-driven web app, you spend most of the time waiting for the database to get back to you. Keeping a thread around while you wait is a waste of memory. Node.js takes a different approach. Everything runs in a single thread, which is woken up whenever an interesting event happens (such as data coming back from the database). This approach has the advantage of using a lot less memory in many situations. The disadvantage is that if you lock that single thread, no one gets data. Because of this, you have to try to keep the main thread as light as possible by delegating work to other processes or Web Workers (still in the planning stages).
To show the event-driven, single thread model at its best, I put it up against apache running PHP. Both node.js and PHP slept for 1s and then exited (perhaps simulating waiting for a complicated DB query to return). I then pointed apache benchmark against the two servers, 10000 requests at a concurrency of 1000 (ab -n 10000 -c 10000 http://localhost…). Node.js handled the load well, taking 13s (out of a possible 10) to finish the requests. On the other hand, apache ran out of threads around the 2000 mark, slowed down my machine, and then stopped answering requests.
The other nice thing about Node.js is that it’s JavaScript. Whatever you think of the language itself, the code-reuse benefits of running the same code on the server and client side is definitely interesting. For the purposes of my demonstration, I made use of a JavaScript implementation of the “Markdown” markup language called Showdown. I threw together a quick “wiki”-like service, which utilized Showdown to provide page rendering and a quick preview of the page. Making use of this library on the server using a small wrapper module was pretty easy. What really interested me about running JS server-side was that someone made an implementation of DOM1, allowing stuff like jQuery to be used on the server. I had the idea that you could use this to easily make an interactive, “ajaxy” app, which would still work if JS is disabled on the client side. Essentially, the client updates its DOM and any functions it runs to do so also run on the server to keep its copy of the DOM in sync. This would take a bit more memory than generating HTML on the fly, but might be cool for apps that display a common interface to all of its users (e.g., an administration panel). The stumbling block is that the node DOM1 implementation doesn’t have a serialization function (DOM -> a HTML string), and I haven’t got around to making one myself.
One of my favourite things about JavaScript is its event-driven nature, and doing this kind of thing on the server side appeals to me. Node.js isn’t the only framework that allows this (e.g., Python’s eventlet), and there are existing web servers (like Nginx) that use an event-driven design to deliver much higher concurrency than Apache. However Node.js forces this pattern more than most. Synchronous aspects are the exception in Node.js rather than the norm. This didn’t seem to get in the way much and this generally forces you to use a design pattern that scales well.
Sharing code between the server and client is interesting, but probably not generally too useful. Sharing rendering code, e.g., preview/render (like in my “wiki” example), or boring stuff like data validation, are probably the main applications. Combined with a DOM serialization function, you could have a client side app that gracefully degrades without as much effort as it normally takes. Generally though, client-side JavaScript has a rather different role than what runs on the server and, hence, there isn’t too much overlap.
Node.js is certainly interesting, and I’m looking forward to playing around with it a bit more. The event-driven thing is cool, but I’d have to see how it stacks up against other event-driven frameworks before being able to make an informed judgement about whether it offers anything extra.
—Stefan is a software engineer who is currently melding his mind with the allhomes.com.au platform.
Justin Smith | |
Post a Comment 
Reader Comments