Reputation: 3353
I have question about node.js inbound/outbound connections. Lets consider my situation or what I want to achieve:
I have for example X inbound http requests per second. For every request I create outbound https request to some third party (they respond me in average 300 milliseconds). When I receive response from this third party I consider this request to be processed. Lets imagine third party have lots and lots of servers and can manage requests in parallel. For every request I have few mongoDB query (which are fast). I use express framework.
In my laptop (4 cores and 4 GB RAM with Windows and lots of another programs instled which could potentially damage performance) I was able to get 150 requests per second but only 40 were processed.
What I don't know: is this actually reality and theoretically I could't achieve more or somewhere in this universe there is some solution/trick which would improve my performance?
Thanks for any suggestions.
Upvotes: 2
Views: 1456
Reputation: 18860
WIth node, there is a very simple optimization you can do for this type of scenario, and that is creating a worker pool. Because of the way the v8 engine works, and how node uses the event loop etc... a single node process can really only hope to use about 50% of a core of a processor. Assuming a relatively standard event loop(not tons of synchronous work to do) which your description seemed to be that typical to a file server(lots of I/O but few processor heavy operations) you can recieve a significan't performance boost by launching many node workers. This minimizes the time when one of your node processes isn't listening for an event, and maximizes the amount of work you CPU does. This of course, won't speed up an individual transaction, but it will allow an individual hardware set up to maximize the amount of transactions it can be servicing at one time.
https://github.com/isaacs/cluster-master
Cluster-master is a convenient tool for managing workers, and keeping the process of creating a worker pool stable and simple, and I believe is installable with NPM.
EDIT:
What can run async, vs what has to run sync isn't always easy to tell. Some rules of thumb for things to look out for:
Node/library calls with sync in the name...
Large functions, with few calls to other functions.
Busy while loops
Some alternatives:
If you have a busy while loop that cannot be avoided. You can do some cool logic, to at least allow your event loop time to grab on to new events. This probably isn't quite valid code(not on a pc with node) but it should demo the concept:
var someInt;
function callBack() {
doWorkWith(someInt);
someInt++;
if(someInt < someMaximum) event.trigger(whileLoop);//The entire event loop will be able to run before we get to the next iteration of callback because we're using events!
}
event.register(whileLoop, callBack);
I don't remember the code for registering events in node, but this logic is good for when you need while loops, as it allows your entire event loop to run for each iteration, where as this:
while(someInt++ < someMax) {
doWorkWith(someInt);
}
Will not let any other events be picked up on, while the while loop is running.
Another thing to look out for is the bad practices of library programmers, particularly I/O libraries. Unless you've taken the chance to look through code, or there are ver positive reviews about a library, assume the worse about any library calls you make, and investigate to see if they're the source of the problem.
Upvotes: 2