Load balancing express app instances - node.js

This is my first load balancing question.
I have written a simple express app to figure out how load balancing works. Also I was taking a look at something like docker. If I had to use Nginx to load balance, should I be running 4 different express instances in 4 different docker containers and then load balance between them using Nginx where Nginx sits in its own container ?
Have I got it right? I am kind of confused

I provided an answer to a similar post some time ago, but here's the important bits in a nutshell:
Yes, it's possible to use Nginx to load balance requests between
different instances of your Node.js services. Each Node.js instance
could be running in a different Docker container.
You can then modify Nginx to load balance between the containers using for example the configuration file mentioned in the link above.
Nginx itself can perfectly run within a Docker container. For these kinds of setups, Docker compose can help you orchestrate the configuration such that you can start up all Nginx and Express containers with a simple command.

Related

Running NodeJS server in production

I have a react + node app which I need to deploy. I am using nginx to serve my front end but I am not sure what to use to keep my nodejs server running in production.
The project is hosted on a windows VM. I cannot use pm2 due to license issues. I have no idea if running the server using nodemon in production is good or not. I have never deployed an app in production, hence I have no idea about appropriate methods.
You may consider forever or supervisor.
Check this blog post on the same.
You can also use docker. You can create multiple docker containers that will run your node server. Now at the nginx level at your host machine you can do load balancing configuration which will route the traffic equally to different docker node containers this will improve your availability and scalability, In heavy traffic you just need to increase the number of docker node containers as and when required. I guess initially 2 containers will be enough to handle traffic (depends on your use case though).
Note:- You can also use forever or supervisor as suggested by #Rajesh Gupta inside your docker containers for running node server. We use PM2 for that.
If you have a database then you can create a separate docker container for the database and map it to a volume in your host machine.
You can learn about docker from here.
Also you can read about load balancing in nginx from here.
Further more to improve your availability you can add a caching layer in between nginx and docker containers. Varnish is the best caching service i have used till date.
PS:- We use a similar but more advanced architecture to run our Ecommerce application that generates 5-10k orders daily. So this is a tested approach with 0 downtime.
Try to dockerize the whole app including the db, caching server (if any) etc.
Here are some examples why:
You can launch a fully capable development environment on any
computer supporting Docker; you don't have to install libraries,
dependencies, download packages, mess with config files etc.
The working environment of the application remains consistent across
the whole workflow. This means the app runs exactly the same for
developer, tester, and client, be it on development, staging or
production server. In short, Docker is the counter-measure for the
age-old response in the software development: "Strange, it works for
me!"
Every application requires a specific working environment: pre-installed applications, dependencies, data bases, everything in specific version. Docker containers allow you to create such environments. Contrary to VM, however, the container doesn't hold the whole operating system—just applications, dependencies, and configuration. This makes Docker containers much lighter and faster than regular VM's.

Can we use both NGINX and PM2 for node.js production deployment?

I am new to Node.js. I have built my first Node.js server. I am doing some research to improve performance of node js server in production. So I learned about NGINX and Process Manager(PM2).
NGINX:
It can load balance the incoming requests.
It can act as reverse proxy for our application.
PM2:
It can divide our application as clusters though it has in built load balancer.
We can monitor and restart application when crashed.
Can we use both for production?
Though load balancer is there in PM2 can I use only PM2?
What is the advantage of using NGINX over PM2?
If I use Load balancer using NGINX and clustering using PM2, will it give better performance than using only one (NGINX or PM2)?
This is a huge topic but let me help and give you some pointers.
Nginx is much more than just a reverse proxy. It can serve static content, can compress the response content, can run multiple apps on different port on the same VM and much more.
PM2 essentially helps you to scale throughput of your service by running it in cluster mode and utilizing all the cores of the box. Read this stackoverflow answer to understand more on this.
Now to answer your question
Can we use both for production?
Yes and you should. Nginx can run on port 80. PM2 can run on port 3000 (or whatever port) which can then manage traffic within the instances of the app.
gzip alone will make a huge difference in the app end user performance.
Here is a good article in case you need code help on how to set it up

Scaling a two-tier MEAN application with Docker on AWS

So my current set-up is a Node.js application that serves up an Angular front-end, a second Node.js application that has Express and serves as an API, and a MongoDB instance. Simply, the client-side app talks to the back-end app and the back-end app talks to MongoDB.
I was looking into how to Dockerize these applications and it seems like some examples use linking. So my question is does linking only work on the same host (meaning a single EC2 instance on AWS) or multiple EC2 instances? If only the former and if I have both apps and Mongo containerized on one instance, how do I scale out? Like if I spin up a second EC2 instance, would I put both containerized Node apps and Mongo again on that second instance? Is having a Mongo container on the same instance with the Node apps a single point of failure? How is that fault tolerant?
Just trying to wrap my head around this and apologize for my ignorance on the subject. Thanks!
You should put each app as well as the MongoDB server in separate containers (which is what I think you intend) and the linking (via Docker-Compose or other method) is just networking. If you use Docker links, it creates a private network. You can create other networks to talk to each other, also to a LAN, WAN, whatever.
Yes, putting them all on the same EC2 instance is creating a SPOF.
If that's a concern, look into: https://docs.docker.com/swarm/networking/
Docker Swarm is fully compatible with Docker’s networking features.
This includes the multi-host networking feature which allows creation
of custom container networks that span multiple Docker hosts.
Or load balance your apps and use an AWS-hosted MongoDB cluster. There are many possible approaches based on your needs and budget.

nodejs, docker, nginx and amazon aws deployment

There have been many questions regarding docker, node and amazon aws and I have read most of them but I haven't got my answer.
I have been working on a production node.js API project for last some weeks and now that the API's are complete I have to deploy them.
There are a total of 2 microservices (this may increase later) and some worker processes. Different components of the system will communicate with each other using SQS and SNS. Each of the microservices uses mongo DB as the nosql storage and mongoose as the ODM. I chose mongolab as the mongoDB hosting provider. Currently I can connect to mongolab DB using MONGOLAB_URI environment variable (obviously this will not be enough during production any suggestion on this one is welcome)
I am going ahead with amazon aws platform.
My thought process is:
I will docerize each of the components. For worker processes it is straight forward.
For microservices I will have 2 docker images which I will deploy using amazon EC2 container service. I will have a third nginx docker image which I will put in front of node applications.
I am planning to create a cluster of 2 machines (c2 large) initially and host these 3 dockerized microservices and nginx images on these machines.
Obviously the node process will run on some port. Lets assume it to be 3100
Till now it is perfectly clear the problem came when I want to exposes these API's to outer world
The microservices exposes some endpoints like
service 1:- /users, /login, /me etc
service 2: /offers, /gifts etc
My Question is:
I want to resolve
mydomain.com/api/v1/users to service1:3100/users
similarly for other API's
I assume this can be done by nginx but I am not much familiar with it.
The constraints are:
I don't want to host each of the microservice on a separate machine (budget constraint).
I don't know which service will run on which machine (this I assume since I read that ec2 container service will automatically start docker processes on random machines and distribute load).
How Can I do this ?

Expressjs to production

I am new to expressjs, I want to deploy an expressjs app to production. Based on my googling, here's the setup on rackspace I am thinking:
1 Load balancer + 2 server + Run app with forever
My questions are:
What engine shall I use to run the app? nginx?
how many app can I run per server?
Thank you.
If you are serving static files or using any of nginx's reverse proxy features, you can use nginx. But if not, since your servers are behind a load balancer, nginx isn't necessary at all.
The rule of thumb is one node.js/express.js process per core. Have a look at cluster to help you manage this. Make sure your load balancer knows about all the node.js processes you are running (and is not just load balancing between one IP/port pair on each server).
Update: Node.js now has cluster built in out of the box.
Also, if you are deploying on Ubuntu you can use upstart instead of forever if you like.
You need nodejs installed on your machine to run nodejs. nginx is a server used for reverse proxy and a load balancer. Also you can run the app through pm2 instead of forever which will handle all the clustering and running your app in background.

Resources