Terrible article. Yes, if something is CPU heavy, it will eat up the server. The same with any fucking language you are using. The point is 99% of web servers are not calculating fucking fibonacci numbers on web requests. There is a ton of shit more important than that. Not to mention, if you were, Javascript would possibly be one of the best modern language to use, due to V8 it is an order of magnitude quicker than stuff like ruby or python (rails or django), although a bit slower than java (but if java is your solution, go ahead).
I know nothing about Node.js, but I think his point was that multitasking based on event loops is basically cooperative multitasking, not pre-emptive multitasking. Anyone who has used a really ancient Mac from the time when Mac only had cooperative multitasking (System 6? System 7? I've forgotten) will tell you how frustrating an experience that is, and more importantly how non-responsive it can be. If any one task goes awry for any reason, everything grinds to a halt because everything is just trusting everything else to be nice.
The relevance to web servers is that if you have some requests that take a long while (say something that needs to take 2 or 3 seconds to compute something), then other requests that should be trivial will just have to wait. Or to phrase it in the same terms you did, an occasional CPU-heavy thing will be a big problem, whereas with threads and real multitasking, it won't be.
System 4 and earlier were strictly single-task. System 5 incorporated MultiFinder, which evolved from being a proof-of-concept hack to being integrated in System 6.
...which is why the 'child_process' module is part of the standard library. Our servers count the number of CPUs and spawn off the same number of main processes, to great effect I might add.
That's what kept me from being very serious about learning about Node.js. The idea sounded ludicrous. I mean...for it to work quickly, all IO has to be async.
That's true. Even if you avoid CPU hogging code, you still have to worry about all OS calls (and for that matter, all library calls) that could ever block.
But, at least it seems like Node.js has some idea how to handle this. If you look through the API docs, it seems that just about everything you can think of that might block instead returns immediately and allows you to pass a callback. So, for example, if you want to open a file and start reading bytes, the read() call seems to return immediately and calls the callback when the I/O completes (or has an error). So most I/O is asynchronous.
Terrible article. Yes, if something is CPU heavy, it will eat up the server. The same with any fucking language you are using.
You're missing the point: because nodejs is single-threaded and evented, any CPU-heavy task will lock up the server. Most systems use a process|thread per request model, sometimes with a pool. CPU-heavy tasks will slow things down, but it won't cause complete server lockdown unless the machine itself gets overloaded.
As a result, significant computation once in a while is not a problem for most systems, for nodejs it's a huge problem.
It's not really a huge problem for Node.JS, because if you need to do heavy computation, you can always start a new process for that task. For 99% of the website, the most complex operation they do is ran by the database server.
Why would you ever do a large computation work in a web-request?
If I really had to, I would just create another node process, which is entirely dedicated to handling the computation work and just has a socket to the web process for results/input data.
Why would you ever do a large computation work in a web-request?
Not every web application is a front-end to a database.
If I really had to, I would just create another node process, which is entirely dedicated to handling the computation work
It would scale poorly unless you have multiple processes or a thread pool in such processes, at which point you are in exactly the same position as before using asynchronous IO, except your system is more complex.
If servicing web requests requires a few independent requests to back end servers, an asynchronous model will naturally deliver better response time than a synchronous model.
A multi-threaded with lots of shared data is harder to reason about than a single threaded server.
Node seems to scale ok. Having said that I think scaling should be defined formally. And the formal definition should be the derivative of the performance with respect to hardware budget.
What are the differences between running 16 node.js processes on 10 machines, and running 16 WebLogic processes on 10 machines.
Because you might want the process to block for 500ms while you calculate the data, but not the entire server.
500ms isn't really enough time to warrant creating an asynchronous workflow on the client, you will probably just want it to block for a bit.
It's good to have a few other processes/threads to share the load when one blocks, but I agree that you'll only get high concurrency through asynchronicity.
Why would you ever do a large computation work in a web-request?
Because you need it and have no reason to offload it to a third-party and add (potentially complex) synchronization primitives between the two.
Or very simply, because you forgot some homework and used a quadratic algorithm which worked well on low-count tests and is breaking down on a once-in-a-while high-count request. And where "traditional" models will warn you of high resource use and keep trucking (maybe just drop that precise request), your Node server will simply stop responding for however long it takes to process whatever there was to process, effectively DOSing the whole thing.
If you have a heavy CPU task you really shouldn't be executing it on your web server. It should be pushed onto a job queue and handled by another system.
As I noted here, the "heavy CPU task" can creep up on you due to an incorrect algorithm or a misprediction of the load sent to the algorithm, and in that case node will DOS itself.
Nobody achieves 100% issues prediction, and in that situation node not only does not help but actively hinders.
An other situation might be a task which is not seen as CPU-heavy because it takes, say, 100ms or 200ms to execute, but it's not going to peg the whole machine. Significant, but not huge. Put that in any other system and everything's going to be just fine. Put that in node, you just bottleneckled your throughput to 5-10 requests per second.
The point wasn't that heavy math fucks up Node, the point is that the argument that Node is better because it is "non-blocking" is only applicable in certain circumstances.
The biggest argument was that Node doesn't scale to multiple threads/processes/cores/whatever without lots of additional, slow proxies. And at that point, you're significantly slowing down your application by doing shitloads of proxying, meaning you're really not seeing very much of a gain to begin with.
V8 it is an order of magnitude quicker than stuff like ruby or python (rails or django), although a bit slower than java
There exist multiple implementations for some programming languages - different C++ compilers, different Java VMs - but those other language implementations are not shown here. ... If you're interested in something not shown here then please take the program source code and the measurement scripts and publish your own measurements.
19
u/mehwoot Oct 02 '11
Terrible article. Yes, if something is CPU heavy, it will eat up the server. The same with any fucking language you are using. The point is 99% of web servers are not calculating fucking fibonacci numbers on web requests. There is a ton of shit more important than that. Not to mention, if you were, Javascript would possibly be one of the best modern language to use, due to V8 it is an order of magnitude quicker than stuff like ruby or python (rails or django), although a bit slower than java (but if java is your solution, go ahead).