Node.js: what, why, how
If you ask around in the developer community about what’s the hottest technology in the recent years, then probably you will get the same answer: Node.js. How hot is that? Its repo now has nearly 20,000 stars, 13,000 commit, and more than 800 contributors on Github now, and that’s just for the node itself as there are even countless libraries, codes, products and websites are based on Node.js. It seems that it is becoming a must-know skill for every developer just because it is so good that everyone likes to use it.
The single-threaded concept is quite important because it is related to Node’s performance. The problem with multiple threads system is that it requires extra coordination works. Node’s way is simple: there is only one thing happening at once, and here is what non blocking I/O fits in - you don’t waste time waiting on things like I/O, so the Node is able to act on event in a very short time.
Traditional server, such as Apache, will create a new thread for each request, and the thread will wait for every I/O or heavy task such as database query or file reading, and then send the response back. There are two problems happening here, the first is it will waste time on waiting - which ultimately increase the response time. Secondly, suppose the server has only 2048MB memory size, and each thread will take 2MB resource from the server, then theoretically the maximum number of connections supported by this single server is 2048 / 2 = 1024. If your expected your total number of user is more than that, then you need to consider adding more server in order to support more users. Node, instead, is single threaded, and its I/O is non-blocking, so with same resource and time, it can handle more connections easily because after receiving one request, it can still receive more requests as it does not wait for the I/O work to be finished, but return the response only when the I/O works are finished and corresponding events are triggered.
A good real-life example is ordering food at a fast food restaurant. When you get in line at the counter, the server taking your order can behave in two ways: one of them is event-driven, and one of them is not. The typical approach is after you asking the server for your order, he will not serve any other customers until he has completed your order. He has to wait for an unknown amount of time for the kitchen to prepare your meals. This way is exactly like the tradition approach of web framework: each server(thread) is allocated to just one customer(request) at a time, the only way to scale up is to add more server(thread), and it is obviously not very efficient because he spends too much time waiting for kitchen(I/O).
Restaurants nowadays have a better way to handle this: they give an order number to each customer after they have ordered food. And the number will be called when the kitchen has prepared the food. This is exactly what Node is doing. In this way, you could serve a lot of customers because you can just give them a number (a callback reference) and call them back if their food is ready in the kitchen. In this way, servers are able to maximize their throughput.
!!! An important thing to notice here is Node’s I/O time is not reduced at all. The I/O time is exactly the same as tradition server, but since Node does not waste time on waiting, it can serve more request at the same time, and hence work more efficiently.
So does it mean that we should just abandon tradition server and replace them by Node? Of course not. Node has its drawback : it is single threaded! What? Didn’t you just tell us this is its advantage? Well, Node will not waste time on waiting for I/O operation, but when the callback is invoked in the main thread and it gets stuck, your server will not be responding anymore since its one and the only one thread is not responding. Node.js is doing only one thing at a time! If the current thing it is working takes a long time, then all requests will have to wait, which really screw up the whole server.
In general, Node.js is good at:
- Real-time applications: such as chat app
- Applications that are highly event driven & are heavily I/O bound
- High traffic, Scalable applications:
It’s better not using Node.js if you need:
- heavy CPU consuming algorithm/work on server: Your server will suffer!
Although the weakness is there, Node.js is still a perfect choice for small project. It is fast enough and extremely easy to develop. Especially you could develop real time application like Chat App within half an hour using Socket.io. But if you are going to build a large enterprise system such as an ERP package or payment server, then our old and stable Apache/Tomcat/Nginx servers are still your best friends. Anyway, I still think every developer at least should try Node.js once, and you will realize how fast and easy you can build a web application.
Node School is probably one of the best resource you can find on the web for learning Node.js. By attempting assignments and works on it, you will have a better understanding of Node and things related to it.
- Tom hughes-croucher & Mike wilson. (2012). Node: Up and Running. : O’Reilly Media.