Is it possible to run sails.js on a node cluster? - node.js

I am currently running an express server using the node js vanilla cluster setup as demonstrated over here:
http://rowanmanning.com/posts/node-cluster-and-express/
I'd like to move the server over to sails.js and I am wondering if anyone knows how to configure sails to support the node cluster (no proxies, just simple cluster).
TX,
Sean.

First thing - if You want to use sessions, You need to use session store. Otherwise session will be not shared between instances of Your app.
Then, The easiest way is to use something like PM2, which can be found here: https://github.com/Unitech/pm2
You dont need to do changes in Your app.js files - it should be written as standard non-clustered sails app. PM2 will do the job.
Just start the app with pm2 start app.js -i x where x is number of instances or use pm2 start app.js -i max which will start instances that are equal to numbers of processors, or processor threads.
PM2 is great and very stable, it has many features to run it smoothly in producation, however it has some flaws in development. If You will ever have a problem with "port already in use" after stopping or even deleting app that was using it - You will have to use pm2 kill which will kill ALL Your apps.
Other than that - its just great - with some additional monitoring tools.

You can use PM2 Library a create different instances like cluster.
For do it you have to use app.js file, like:
pm2 start app.js
If you want to run the max number of instances availables:
pm2 start app.js -i max
check the documentation for more: https://github.com/Unitech/pm2

Related

How to know if PM2 runs my NodeJS app?

I've been wondering how one knows if PM2 or other similar apps runĀ a NodeJS app? Not just knowing that the app is ran as a child process, but specifically know that PM2 is the one runs it.
I did console.dir(process), but I had yet to find anything that referred to PM2.
You should have a lot of informations in the process environnement, pm2 use it to transfer variable into application.
You can see here that the ProcessContainer (the wrapper around your application) set env var from process.env.pm2_env

Cluster and Fork mode difference in PM2

I've searched a lot to figure out this question, but I didn't get clear explanation. Is there only one difference thing that clustered app can be scaled out and forked app cannot be?
PM2's public site explains Cluster mode can do these feature but no one says about pros of Fork mode (maybe, it can get NODE_APP_INSTANCE variable).
I feel like Cluster might be part of Fork because Fork seems like to be used in general. So, I guess Fork means just 'forked process' from the point of PM2 and Cluster means 'forked process that is able to be scaled out'. Then, why should I use Fork mode?
The main difference between fork_mode and cluster_mode is that it orders pm2 to use either the child_process.fork api or the cluster api.
What does this means internally?
Fork mode
Take the fork mode as a basic process spawning. This allows to change the exec_interpreter, so that you can run a php or a python server with pm2. Yes, the exec_interpreter is the "command" used to start the child process. By default, pm2 will use node so that pm2 start server.js will do something like:
require('child_process').spawn('node', ['server.js'])
This mode is very useful because it enables a lot of possibilities. For example, you could launch multiple servers on pre-established ports which will then be load-balanced by HAProxy or Nginx.
Cluster mode
The cluster will only work with node as it's exec_interpreter because it will access to the nodejs cluster module (eg: isMaster, fork methods etc.). This is great for zero-configuration process management because the process will automatically be forked in multiple instances.
For example pm2 start -i 4 server.js will launch 4 instances of server.js and let the cluster module handle load balancing.
Node.js is single-thread.
That means only 1 core of your Intel quad-core CPU can execute the node application.
It called: fork_mode.
We use it for local dev.
pm2 start server.js -i 0 helps you running 1 node thread on each core of your CPU.
And auto-load-balance the stateless coming requests.
On the same port.
We call it: cluster_mode.
Which is used for the sake of performance on production.
You may also choose to do this on local dev if you want to stress test your PC :)
Documentation and sources are really misleading here.
Reading up on this in the sources, the only differences seems to be, that they use either node cluster or child_process API. Since cluster uses the latter, you are actually doing the same. There is just a lot more custom stdio passing around happening inn fork_mode. Also cluster can only be communicated with via strings, not objects.
By default you are using fork_mode. If you pass the the -i [number]-option, you're going into cluster_mode, which you generally aim for w/ pm2.
Also fork_mode instance probably can't listen on the same port due to EADDRINUSE. cluster_mode can. This way you also can structure you app to run on the same port being automatically load balanced. You have to build apps without state then though e.g. sessions, dbs.

How to achieve zero downtime redeployment in Node.js

What is the easiest way to achieve zero downtime for my Node.js application?
I have an app that requires the following steps for redeployment:
npm install
node_modules/.bin/bower install
node_modules/.bin/gulp
The result of these operations is the ready-to-run application in the generated by the gulpfile.js directory named build. In this directory I have a currently-running instance of the same application (currently launched via forever like this -- forever start server.js).
As far as I know, it is not possible to achieve zero downtime via forever module, so I decided to choose another way to do it.
I saw pm2 but I found it very complex tbh (prove me wrong if you don't feel the same).
I also saw naught but I can't even start my application via naught start server.js -- it doesn't even print anything in stdout / stderr.
I also saw up-time but I didn't get the idea -- how will it handle situation when I run gulp that should replace files in the directory where currently-running instance work at the moment?
Regarding of handling replaced files during build: if these files is used by Node.js app then all changes will be applied upon process restart (since these files are loaded into memory), browser frontend files could also be cached in application memory to achieve similar behavior (changes applied only upon restart or/and cache invalidation).
We're using pm2 in cluster mode.
pm2 start app.js -i
The above command starts app.js in cluster mode on all available CPU cores.
zero downtime restart:
pm2 gracefulReload all
this command restarts all processes sequentially, so if you have more than one process up and running there is always at least one process that servers requests during restart.
If you have only one process of app.js you can start it in cluster mode and run pm2 scale app.js 2 (starts one more process) then pm2 gracefulReload all and then pm2 scale app.js 1 (removes previously started process).
Though I think app restarting is not main problem of zero downtime deployment, we've not managed to handle DB migrations, so full app shutdown is needed to apply DB changes. Also there could be an issue with browser frontend files when during deploy user obtained the new version of them, but AJAX request is processed by old version of server process, in this case sticky sessions and API versioning came to the rescue.

What is the different between using StrongLoop's "slc run" and "node app.js"

I'm working through the StrongLoop's getting started instructions and created my sample app. Whilst the instructions tell me to use:
slc run .
to start my application, I noticed I can equally run my application with:
node app.js
and get the same result. Obviously by using the second approach I can integrated my StrongLoop application with tools such as forever.
So my question is, what extra benefits does slc run offer? Does it have functionalities such auto restart etc?
You can do more with slc than node app.js.
slc is a command line tool for StrongLoop, which has more features. If you just want to run the app, it doesn't matter much, but if you want to do more, you can.
Here's the documentation: http://docs.strongloop.com/display/SLC/StrongLoop+Controller
It doesn't have much features for development (such as auto restart and such), but it will help with managing servers and what not.
My favorite feature is scaling a node app using slc.
You can do "slc run . size 2". This will spin up 1 master and 1 worker process which is part of a single cluster. Now if my workload increases, and resources are low, which I know using strongOps monitoring (slc strongops) and I want to scale the app without having to stop the app and re-engineer, I can just do the following:
"slc clusterctl size 4". This will spin up 2 more worker processes and automatically attach them to the same application cluster at run-time. The master will auto distribute the workload now to the new processes.
This is built on top of node cluster module. But there is much more to it. Used cluster-store to store shared cluster state objects too.
Another feature is "slc debug". Launches Node Inspector and brings the application code in runtime context and helps me in debugging, load source maps and iterate through test runs.
Based on the latest release at the moment (v2.1.1), the main immediate benefit of running slc run instead of node app.js is you get a REPL at the same time (lib/run-reple.js#L150L24). Looks like all you have to do is have main set properly in package.json, since it uses Module._load().
If you run slc run app.js you get no benefit as far as I can tell: lib/commands/run.js#30.
Yay open source! https://github.com/strongloop/strong-cli
One of my favorite features is 'slc debug app.js' which brings up node-inspector for debugging . its nice CLI sugar. But of course you can totally run node and configure this manually.
I created a Linux init.d Daemon script which you can use to run your app with slc as service:
https://gist.github.com/gurdotan/23311a236fc65dc212da
Might be useful to some of you.
slc run
it can be only used for strong loop application
while node . or node [fileName]
can be used to execute any Nodejs file

Run at startup and monitor redis and node.js processes

I want to deploy node.js app which depends on redis. Both processes will run on the same VPS. There are plenty of examples on how to daemonize and monitor node and I've also found some uncommented configuration for redis. How do I put it together? Can I just combine these two snippets in one monitrc file?
You could use Supervisord to orchestrate the launch of Redis and your NodeJS apps (use the priority parameter to start Redis before your apps). Supervisord will automatically restart your NodeJS app if they crash.
You can then setup monit over it to be alerted when something wrong happens and to restart your NodeJS processes if they use too much memory/cpu or if they are not accessible anymore from a specific port.

Resources