How to achieve zero downtime redeployment in Node.js - 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.

Related

PM2 - Is this considered a good practice

In my project I have several servers which run NodeJS applications using PM2, those were not created by me. I am not that familiar with the PM2. Now I need to start a new server, which is simply a CRON process that queries an ElasticSearch instance.
There are no routes or anything in it, just a CRON with some logging.
Here is my dilemma. I have played with PM2 and I become somewhat familiar with what is it, and what it does. But the question is how shall I run it?
The previous projects do have PM2 config.json with many parameters, and they are started in cluster mode (handled with Nginx), and when I start them I see all process's becoming daemons. But in my case I don't need that. I just need it to run as a single service.
In other words if I use the configuration file to run the PM2, I see it spawned in cluster mode, and it creates chaos as my CRON is fired many times. I don't need that. If I start it in Fork mode, it also spawns instances, but all of them die, except one (due to which they are using same port). I also don't need that.
I just need single service.
I managed to run the my CRON app.js with the singe line, simple as:
PM2 start app.js. It runs in single thread, and I can see it's info with PM2 status. All fine.
If I run it with the single line(as in my case), is it considered ok? Based in my knowledge if I use config.json, it will always run it in fork or cluster.
Is it ok to run it in single line, or do I need still to use a config.json file.
If you only need one process to be run, as is the case, you're doing the right thing.

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.

All my Node.js apps crash unpredictably at the same time

I've written two simple Node.js apps, each of which run a server on a port (1337 and 1338), and using PM2 (and Keymetrics) to keep them alive, but every few days all three Node.js apps (including PM2) crash simultaneously. I'm fairly new to Node.js and am not sure how to investigate the source of the problem.
DETAILS:
The two servers respond to incoming GET requests. One is to automatically do a GIT fetch/pull in response to a Bitbucket trigger, and the other converts a URL to PDF and sends the PDF back to the browser (using wkhtmltopdf). They both work fine while they're running.
I'm running Node.js v0.12.4.
When the three apps go down, my first indication is from my Uptime (https://github.com/fzaninotto/uptime) instance on OpenShift which emails me to say one of my Node.js servers is down, returning "connect ECONNREFUSED".
A couple of minutes later Keymetrics emails me saying "Agent is offline: Keymetrics Agent seems to be offline".
In other words, ALL my node.js stuff seems to go down at the same time; neither of the two apps nor even PM2 are running. I thought Node spawned a process for each app, so how could they all go down at once?
WHAT I'VE TRIED:
I've tried digging through the ~/.pm2/pm2.log but haven't been able to find anything useful in there. Maybe I just don't know what to look for.
$ pm2 resurrect always brings everything back to life just fine.
Please upgrade to latest PM2 version:
$ npm install pm2 -g
$ pm2 update

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

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

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

Resources