nodejs - 对于在集群模式下运行的应用程序,我应该如何使用 nginx 和 pm2?

Posted

技术标签:

【中文标题】nodejs - 对于在集群模式下运行的应用程序,我应该如何使用 nginx 和 pm2?【英文标题】:nodejs - How should i use nginx along with pm2 for my application running in cluster mode? 【发布时间】:2017-10-01 04:07:41 【问题描述】:

我给了一个任务,在我的应用程序中使用 nginx 和 pm2。我应该如何在集群模式下使用 pm2 运行的 nodejs 应用程序前面使用 nginx?

又了解到pm2本身自带负载均衡器,那我为什么要使用nginx呢?

【问题讨论】:

【参考方案1】:

这是一个老问题,但我最近不得不这样做,我觉得更完整的答案可能对像我一样从谷歌登陆的任何人都有帮助。我假设您在较小的设置中使用 nginx 作为多台服务器的负载平衡器,并且根据 PM2 文档,您的应用程序是 无状态。如果它不是无状态的,您可能会遇到集群模式的问题。

还了解到pm2本身提供了内置的负载均衡器,为什么 那我应该使用 nginx 吗?

首先,PM2 和 Nginx 都可以作为负载均衡器运行。人们常说 NodeJS 是“单线程”的,因此一次只能使用一个 CPU 核心 - PM2 集群模式在一个主进程下运行同一个 NodeJS 应用程序的多个实例,让您可以在主机上使用更多内核。 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).

您可以在集群模式下初始化 PM2,如下所示:pm2 start -i NUMBER_OF_CORES(e.g 2) npm --name APP_NAME -- run start

同时,Nginx 还可以对 NodeJS 应用程序进行负载平衡 - 但是它会使用 upstream 块来实现。这需要不同的主机和不同的 IP,可能看起来像这样:

 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;
         
    

您可以看到这两个选项之间的区别主要在于 nginx 允许您跨多个 IP、端口和服务器进行负载平衡,而 PM2 是一个快速简单的负载平衡器,用于共享 CPU 资源的应用程序。 您可以尝试同时使用这两种方法,方法是使用 nginx 对虚拟机之间的请求进行负载平衡,然后使用 PM2 确保每台机器都完全使用其内核,我想。

现在,尽管如此,在集群模式下在 PM2 前面使用 nginx 的主要方式是,如果您使用它从客户端呈现的应用程序(例如反应)提供静态内容并与 nodejs 通信通过 HTTP 调用的后端,您希望在其中跨 CPU 内核进行负载平衡。在这种情况下,Nginx 将充当 1) 来自前端的静态内容服务器 2) 与在集群模式下运行的后端通信的反向代理。在这种情况下,您的 nginx 配置可能如下所示:


        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/;
        

当然,您可以通过调整位置块以类似的方式代理传递服务器端呈现的应用程序;)

【讨论】:

【参考方案2】:

虽然 guruwinder 写的所有内容都是正确的,但问题表明您“被赋予了一项任务”。要记住的另一点是 PM2 也适用于 Nginx 不提供的其他一些东西。 PM2 让您以守护进程的形式启动和重新启动;监控您的控制台日志记录;快速了解您的服务器和服务背后发生的事情;多个实例来负载平衡和集群处理。换句话说,使用 PM2 比负载平衡有更多的好处。我一直在使用它,并且已经在 AWS、Azure 以及本地 Mac 和 Windows 上使用过它。有时需要一些技巧才能做到正确(尤其是在 Windows 上),但这样做的好处是值得的。

因此,您需要 Nginx 来获得上面提到的所有功能以及更多功能,并且使用 PM2 运行它会给您的服务提供更大的灵活性。但是,使用 node(正确)运行 PM2 将允许微调和实际了解您的 node 应用程序在后台执行的操作。

因此,像往常一样使用 Nginx,并在后台使用 PM2 和 Node 应用程序。至于负载平衡,应该根据您对 Nginx 的控制量来决定。

希望这对您有所帮助。

【讨论】:

【参考方案3】:

如果您使用 Nginx 的唯一原因是负载平衡,那么您可以忽略它。但我必须警告你,与 Nginx 相比,pm2 更容易崩溃。

就个人而言,我建议您坚持使用 Nginx,它提供了诸如提供静态文件、进行重定向、处理 SSL 证书和提供开箱即用的错误页面等功能。

在 nodejs 前面使用 Nginx 最简单的方法是代理传递请求到 nodejs 正在使用的端口。但您可能希望在执行此操作之前应用更多配置更改。此外,nodejs 几乎可以做 Nginx 可以做的所有事情,但它并不是要那样做的。

查看以下链接:

    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

【讨论】:

以上是关于nodejs - 对于在集群模式下运行的应用程序,我应该如何使用 nginx 和 pm2?的主要内容,如果未能解决你的问题,请参考以下文章

Docker环境下创建Redis集群出现ERR Invalid node address specified: redis1:6379错误

Yarn模式下Apache HAWQ的运行

使用 YARN 在集群模式下运行 spark 时出现 java.io.FileNotFoundException

集群模式下的 Trafodion 与 spark

纱线集群模式下的 Pyspark

aliyun-ons (node版)之 集群模式下模拟广播消费