简体   繁体   中英

nodejs - How should i use nginx along with pm2 for my application running in cluster mode?

I have given a task to use nginx and pm2 in my application. How should i use nginx infront of my nodejs application which is running using pm2 in cluster mode?

Also learned that pm2 itself provides built-in load balancer, why should i use nginx then?

If the only reason you are using Nginx, is to load balance then you can give it a miss. But I must warn you that pm2 breaks down more compared to Nginx.

Personally, I would suggest you stick to Nginx it provides things like serving static files, doing redirects, handling SSL certificates and serving error pages out of the box.

The simplest way to use Nginx in front of nodejs is to proxy pass the requests to port that is being used by nodejs. But you would probably want to apply some more config changes before you do that. Also, nodejs can do almost everything that Nginx can do, but it was not meant to do that.

Check out the following links:

  1. https://www.quora.com/Should-I-host-a-node-js-project-without-nginx 2. Load balancing since Node v0.12.2 - cluster, pm2 or nginx

Bit of an old question this but I recently had to do this and I feel like a more complete answer might be helpful to anyone who lands from google like I did. I'm assuming you're on a smaller set up not using nginx as a load balancer for multiple servers, and that your application is stateless per the PM2 documentation. If it isn't stateless you can run into problems with cluster mode.

Also learned that pm2 itself provides built-in load balancer, why should i use nginx then?

Firstly both PM2 and Nginx can operate as load balancers. It is often said that NodeJS is "single-threaded" so can only utilize one CPU core at a time - PM2 in cluster mode runs multiple instances of the same NodeJS app under a master process, allowing you to utilize more cores on the host machine. PM2 does this without requiring each instance of the app run on a different port (although it could) or IP (which I'll get to) .

You can initialize PM2 in cluster mode with something like this: pm2 start -i NUMBER_OF_CORES(eg 2) npm --name APP_NAME -- run start

Meanwhile, Nginx can also load balance NodeJS apps - however it will do so using the upstream block. This takes different host machines and different IPs and might look something like this:

 upstream app_servers {
        server 127.0.0.1:3000;
        server 127.0.0.1:3001;
        server 127.0.0.1:3002;
        server 127.0.0.1:3002; 
}

server {
         listen 80 ;
        gzip on;
        root /var/www/html;

        index index.html index.htm;
        server_name FRONTURL; 

        location / {
        try_files $uri /index.html;
        }

        location /api/ {
        proxy_set_header   X-Real-IP $remote_addr;
        proxy_set_header   Host      $http_host;
        proxy_pass http://app_servers;
        } 
    }

You can see the difference between these two options is primarily that nginx allows you to load balance across multiple IPs, ports and servers, whilst PM2 is a quick and simple load balancer for apps sharing a CPU resource. You could try to use both by using nginx to load balance requests across VMs, and then PM2 to ensure each machine is using its cores completely, I suppose.

Now, despite all of this, the main way you will use nginx in-front of PM2 in cluster mode is if you are using it to serve static content from a client side rendered app (eg react) and communicating with a nodejs backend through HTTP calls where you want to load balance across CPU cores. In this case Nginx would serve as 1) A static content server from the frontend 2) A reverse proxy to communicate with the backend running in cluster mode. In this case your nginx config might look like this:

{
        listen 80 ;
        gzip on;
        root /var/www/html;

        index index.html index.htm;
        server_name FRONTURL; 

        location / {
        try_files $uri /index.html;
        }

        location /api/ {
        proxy_set_header   X-Real-IP $remote_addr;
        proxy_set_header   Host      $http_host;
        proxy_pass http://localhost:NODEJS_PORT/;
        }
}

And, of course, you could proxy pass a server side rendered app in a similar fashion by tweaking the location block ;)

While everything written by guruwinder is correct the question states you were "given a task". The other point to keep in mind is that PM2 is also great for some other things, which are not supplied by Nginx. PM2 gives you wailing to start and restart as aa daemon; monitor your console logging; a quick understanding of what is going on under the hood of your server and services ; multiple instances to load balancing and cluster handling. In other words, there is a lot more to be gained from using PM2 then the load balancing. I always use it and have used it on AWS, Azure, and local Mac and Windows. Sometimes it takes a bit of finesse to get right (especially on Windows) but the upside is worth it.

So u require Nginx for all the abilities and more mentioned above and running that with PM2 will give you more flexibility over your services. However, running PM2 as well with node (correctly) will allow a fine tuning and actual understanding of what your node app is doing under the hood.

So use Nginx as you always would and PM2 in the background with Node for the node app. As to load balancing, that should be decided based upon the amount of control you have over the Nginx.

Hope some of this helps.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM