37

I am new to Node.js and am currently questioning its reliability.

Based on what I've seen so far, there seems to be a major flaw: any uncaught error/exceptions crashes the server. Sure, you can try to bullet-proof your code or put try/catch in key areas, but there will almost always be bugs that slip through the crack. And it seems dangerous if one problematic request could affect all other requests. There are 2 workarounds that I found:

  1. Use daemon or module like forever to automatically restart the server when it crashes. The thing I don't like about this is that the server is still down for a second or two (for a large site, that could be hundreds (of thousands?) of request).

  2. Catch uncaught exceptions using process.on('uncaughtException'). The problem with this approach (as far as I know) is that there is no way to get a reference to the request that causes the exception. So that particular request is left hanging (user sees loading indicator until timeout). But at least in this case, other non-problematic requests can still be handled.

Can any Node.js veteran pitch in?

pixelfreak
  • 17,714
  • 12
  • 90
  • 109
  • 6
    I don't buy the bit about "hundreds of thousands" of lost requests on a large site. A large site will be horizontally scaled so a single process will only ever affect a small fraction of total traffic. – Kevin Mar 04 '12 at 20:20
  • 1
    possible duplicates: http://stackoverflow.com/questions/7310521/node-js-best-practice-exception-handling http://stackoverflow.com/questions/9181027/node-js-doesnt-display-entire-error-message-on-uncaughtexception-is-it-possibl although I seem to understand the accepted answers are not satisfying? – Dirk Mar 04 '12 at 20:22
  • 1
    @Kevin which might still be in the hundreds or anyway simply unacceptable – Eugen Rieck Mar 04 '12 at 20:22
  • @Kevin Okay, smaller number of requests in a load-balanced setup – pixelfreak Mar 04 '12 at 20:28
  • A large site would have more than one Node process running. Your fears are unfounded. But, even if there is one process, it shouldn't be down for more than a few ms. – JP Richardson Mar 04 '12 at 20:32
  • 1
    As JP said Nodejs has clustering support http://nodejs.org/api/cluster.html also there are child processes which can be restarted by the master process. – Maleck13 Mar 04 '12 at 21:06
  • Thanks, it's experimental, but I'll investigate. Mind putting it in the answer section so it can be rated and/or accepted? – pixelfreak Mar 04 '12 at 21:18
  • 1
    I'm really concerned by this issue as well - it's why I'm hesitating to use Node.js for a REST api in a new project. – Oved D Mar 17 '12 at 16:43

4 Answers4

4

For automatic restarts and load-balancing, I'd suggest you check out Learnboost's up balancer.

It allows you to reload a worker behind the load-balancer without dropping any requests. It stops directing new requests towards the worker, but for existing requests that are already being served, it provides workerTimeout grace period to wait for requests to finish before truly shutting down the process.

You might adapt this strategy to be also triggered by the uncaughtException event.

pixelfreak
  • 17,714
  • 12
  • 90
  • 109
zzen
  • 1,259
  • 10
  • 13
  • in many instances its better to let the node crash on unexpected exceptions and with something like up your restarts can be invisible to the visitor. When I was using nginx for php pages I've learned that php workers crash all the time and you don't know this as an apache user because apache does the same thing as up, apparently. Makes me think that apache might be able to be configured for node hmmm.... – Bijou Trouvaille Mar 22 '12 at 07:52
2

You have got full control of the base process, and that is a feature.

If you compare Node to an Apache/PHP setup the latter is really just equivalent to having a simple Node server that sends each incoming request to it's own process which is terminated after the request has been handled.

You can make that setup in Node if you wish, and in many cases something like that is probably a good idea. The great thing about Node is that you can break this pattern, you could for instance have the main process or another permanent process do session handling before a request is passed to it's handler.

Node is a very flexible tool, that is good if you need this flexibility, but it takes some skill to handle.

aaaaaaaaaaaa
  • 3,630
  • 1
  • 24
  • 23
  • 1
    Yeah, it's a double-edge sword...most people who are drawn to Node does not necessarily have the knowledge or desire to build the "right" server setup properly. Just like no one really cared much about the recent Ruby security flaws until something happens. I personally am attracted to Node because I am very familiar with Javascript. I feel like there should be multiple flavors of Node out-of-the-box to handle various scenarios. – pixelfreak Mar 07 '12 at 19:50
1

Exceptions don't crash the server, they raise exceptions.

Errors in node.js that bring down the entire process are a different story.

Your best bet (which you should do with any technology), is just test it out with your application as soon as possible to see if it fits.

drudru
  • 4,933
  • 1
  • 19
  • 19
1

An uncaught exception will, if not caught, crash the server. Something like calling a misspelled function. I use process.on('uncaughtException') to capture such exceptions. If you use this then, yes, the error sent to process.on('uncaughtException') is less informative.

I usually include a module like nomnom to allow for command-line flags. I include one called --exceptions which, when set, bypasses process.on('uncaughtException'). Basically, if I see that uncaught exceptions are happening then I, in development, start up the app with --exceptions so that when that error is raised it will not be captured, which causes Node to spit out the stack trace and then die. This tells you what line it happened on, and in what file.

Capturing the exceptions is one way to deal with it. But, like you said, that means that if an error happens it may result in users not receiving responses, et cetera. I would actually recommend letting the error crash the server. (I use process.on('uncaughtException') in apps, not webservers). And using forever. The fact is that it is likely better for the webserver to crash and then expose what you need to fix.

Let's say you used PHP instead of Node. PHP does not abruptly crash the server (since it doesn't really serve). It spits out really ugly errors. Sure, it doesn't result in a whole server going down and then having to come back up. Nobody wants their clients to have any downtime. But it also means that a problem will persist and will be less noticeable. We've all seen sites that have said errors, and they don't get patched very fast. If such a bug were to take everything down for one small blip (which honestly its not all that bad in the larger picture) then it would surely call attention to itself. You would see it happen and would track that bug down.

The fact is that bugs will exist in any system, independent of language or platform. And it is arguably better for them to be fatal in order for you to know they happened. And over time it causes you to become more aware of how these error occur. I don't know about you, but I know a lot of PHP devs who make the same common mistakes time after time.

Marshall
  • 4,716
  • 1
  • 19
  • 14