关于Node.js + Nginx:Node.js + Nginx – 现在怎么办?

Node.js + Nginx - What now?

我在我的服务器上设置了Node.js和Nginx。 现在我想使用它,但是,在我开始之前有2个问题:

  • 他们应该如何一起工作? 我该如何处理这些要求?
  • Node.js服务器有2个概念,其中一个更好:

    一个。 为需要它的每个网站创建单独的HTTP服务器。 然后在程序开始时加载所有JavaScript代码,因此代码被解释一次。

    湾 创建一个处理所有Node.js请求的Node.js服务器。 这将读取所请求的文件并篡改其内容。 因此,每个请求都会解释文件,但服务器逻辑要简单得多。

  • 我不清楚如何正确使用Node.js。


    Nginx作为前端服务器工作,在这种情况下代理请求到node.js服务器。因此,您需要为节点设置nginx配置文件。

    这就是我在Ubuntu框中所做的:

    /etc/nginx/sites-available/处创建文件yourdomain.com

    1
    vim /etc/nginx/sites-available/yourdomain.com

    你应该有这样的东西:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    # the IP(s) on which your node server is running. I chose port 3000.
    upstream app_yourdomain {
        server 127.0.0.1:3000;
        keepalive 8;
    }

    # the nginx server instance
    server {
        listen 80;
        listen [::]:80;
        server_name yourdomain.com www.yourdomain.com;
        access_log /var/log/nginx/yourdomain.com.log;

        # pass the request to the node.js server with the correct headers
        # and much more can be added, see nginx config options
        location / {
          proxy_set_header X-Real-IP $remote_addr;
          proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
          proxy_set_header Host $http_host;
          proxy_set_header X-NginX-Proxy true;

          proxy_pass http://app_yourdomain/;
          proxy_redirect off;
        }
     }

    如果您希望nginx(> = 1.3.13)处理websocket请求,请在location /部分添加以下行:

    1
    2
    3
    proxy_http_version 1.1;
    proxy_set_header Upgrade $http_upgrade;
    proxy_set_header Connection"upgrade";

    完成此设置后,您必须启用上面配置文件中定义的站点:

    1
    2
    cd /etc/nginx/sites-enabled/
    ln -s /etc/nginx/sites-available/yourdomain.com yourdomain.com

    /var/www/yourdomain/app.js创建节点服务器应用程序并在localhost:3000处运行它

    1
    2
    3
    4
    5
    6
    7
    8
    var http = require('http');

    http.createServer(function (req, res) {
        res.writeHead(200, {'Content-Type': 'text/plain'});
        res.end('Hello World
    ');
    }).listen(3000,"127.0.0.1");
    console.log('Server running at http://127.0.0.1:3000/');

    测试语法错误:

    1
    nginx -t

    重启nginx:

    1
    sudo /etc/init.d/nginx restart

    最后启动节点服务器:

    1
    cd /var/www/yourdomain/ && node app.js

    现在你应该在yourdomain.com上看到"Hello World"

    关于启动节点服务器的最后一点注意事项:您应该为节点守护程序使用某种监视系统。有关upstart和monit的节点上有一个很棒的教程。


    您还可以使用nginx设置多个域,转发到多个node.js进程。

    例如,要实现这些:

    • domain1.com - >到本地运行的Node.js进程http://127.0.0.1:4000
    • domain2.com - >到本地运行的Node.js进程http://127.0.0.1:5000

    在/ etc / nginx的/启用的站点 - / DOMAIN1

    1
    2
    3
    4
    5
    6
    7
    8
    9
    server {
        listen 80;
        listen [::]:80;
        server_name domain1.com;
        access_log /var/log/nginx/domain1.access.log;
        location / {
            proxy_pass    http://127.0.0.1:4000/;
        }
    }

    在/ etc / nginx / sites-enabled / domain2中

    1
    2
    3
    4
    5
    6
    7
    8
    9
    server {
        listen 80;
        listen [::]:80;
        server_name domain2.com;
        access_log /var/log/nginx/domain2.access.log;
        location / {
            proxy_pass    http://127.0.0.1:5000/;
        }
    }


    您还可以在一个服务器配置中为应用程序添加不同的URL:

    • yourdomain.com/app1/* - >到本地运行的Node.js进程
      http://127.0.0.1:3000
    • yourdomain.com/app2/* - >到Node.js进程
      在本地运行http://127.0.0.1:4000

    在/ etc / nginx / sites-enabled / yourdomain中:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    server {
        listen 80;
        listen [::]:80;
        server_name yourdomain.com;

        location ^~ /app1/{
            proxy_set_header X-Real-IP $remote_addr;
            proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
            proxy_set_header Host $http_host;
            proxy_set_header X-NginX-Proxy true;
            proxy_pass    http://127.0.0.1:3000/;
        }

        location ^~ /app2/{
            proxy_set_header X-Real-IP $remote_addr;
            proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
            proxy_set_header Host $http_host;
            proxy_set_header X-NginX-Proxy true;
            proxy_pass    http://127.0.0.1:4000/;
        }
    }

    重启nginx:

    1
    sudo service nginx restart

    启动应用程序

    节点app1.js

    1
    2
    3
    4
    5
    6
    7
    var http = require('http');
    http.createServer(function (req, res) {
        res.writeHead(200, {'Content-Type': 'text/plain'});
        res.end('Hello from app1!
    ');
    }).listen(3000,"127.0.0.1");
    console.log('Server running at http://127.0.0.1:3000/');

    节点app2.js

    1
    2
    3
    4
    5
    6
    7
    var http = require('http');
    http.createServer(function (req, res) {
        res.writeHead(200, {'Content-Type': 'text/plain'});
        res.end('Hello from app2!
    ');
    }).listen(4000,"127.0.0.1");
    console.log('Server running at http://127.0.0.1:4000/');


    我通过Nginx代理独立的Node Express应用程序。

    因此,可以轻松安装新的应用程序,我也可以在不同位置的同一台服务器上运行其他内容。

    以下是有关使用Nginx配置示例进行设置的更多详细信息:

    Deploy multiple Node applications on one web server in subfolders with Nginx

    Things get tricky with Node when you need to move your application from from localhost to the internet.

    There is no common approach for Node deployment.

    Google can find tons of articles on this topic, but I was struggling to find the proper solution for the setup I need.

    Basically, I have a web server and I want Node applications to be mounted to subfolders (i.e. http://myhost/demo/pet-project/) without introducing any configuration dependency to the application code.

    At the same time I want other stuff like blog to run on the same web server.

    Sounds simple huh? Apparently not.

    In many examples on the web Node applications either run on port 80 or proxied by Nginx to the root.

    Even though both approaches are valid for certain use cases, they do not meet my simple yet a little bit exotic criteria.

    That is why I created my own Nginx configuration and here is an extract:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    upstream pet_project {
      server localhost:3000;
    }

    server {
      listen 80;
      listen [::]:80;
      server_name frontend;

      location /demo/pet-project {
        alias /opt/demo/pet-project/public/;
        try_files $uri $uri/ @pet-project;
      }

      location @pet-project {
        rewrite /demo/pet-project(.*) $1 break;

        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header Host $proxy_host;
        proxy_set_header X-NginX-Proxy true;

        proxy_pass http://pet_project;
        proxy_redirect http://pet_project/ /demo/pet-project/;
      }
    }

    From this example you can notice that I mount my Pet Project Node application running on port 3000 to http://myhost/demo/pet-project.

    First Nginx checks if whether the requested resource is a static file available at /opt/demo/pet-project/public/ and if so it serves it as is that is highly efficient, so we do not need to have a redundant layer like Connect static middleware.

    Then all other requests are overwritten and proxied to Pet Project Node application, so the Node application does not need to know where it is actually mounted and thus can be moved anywhere purely by configuration.

    proxy_redirect is a must to handle Location header properly. This is extremely important if you use res.redirect() in your Node application.

    You can easily replicate this setup for multiple Node applications running on different ports and add more location handlers for other purposes.

    来自:http://skovalyov.blogspot.dk/2012/07/deploy-multiple-node-applications-on.html


    具有Nginx配置的Node.js。

    1
    $ sudo nano /etc/nginx/sites-available/subdomain.your_domain.com

    添加以下配置,以便当我们来自"subdomain.your_domain.com"时,Nginx充当代理重定向到来自服务器的端口3000流量

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    upstream subdomain.your_domain.com {
      server 127.0.0.1:3000;
    }
    server {
      listen 80;
      listen [::]:80;
      server_name subdomain.your_domain.com;
      access_log /var/log/nginx/subdomain.your_domain.access.log;
      error_log /var/log/nginx/subdomain.your_domain.error.log debug;
      location / {
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarder-For $proxy_add_x_forwarded_for;
        proxy_set_header Host $http_host;
        proxy_set_header X-NginX-Proxy true;
        proxy_pass http://subdomain.your_domain.com;
        proxy_redirect off;
      }
    }

    回答你的问题2:

    我会使用选项b,因为它消耗的资源少得多。使用选项'a',每个客户端将导致服务器消耗大量内存,加载您需要的所有文件(即使我喜欢php,这是它的问题之一)。使用选项'b',您可以加载库(可重用代码)并在所有客户端请求中共享它们。

    但是要知道,如果你有多个核心,你应该调整node.js来使用它们。


    我在Github中创建了一个存储库,您可以克隆,vagrant-node-nginx-boilerplate

    基本上/var/www/nodeapp的node.js app是

    1
    2
    3
    4
    5
    6
    7
    8
    var http = require('http');
    http.createServer(function (req, res) {
      res.writeHead(200, {'Content-Type': 'text/plain'});
      res.end('Hello World
    ');
    }).listen(4570, '127.0.0.1');

    console.log('Node Server running at 127.0.0.1:4570/');

    /etc/nginx/sites-available/的nginx配置是

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    server {
            listen 80 default_server;
            listen [::]:80 default_server;

            root /var/www/nodeapp;
            index index.html index.htm;

            server_name localhost;

            location / {
              proxy_pass http://127.0.0.1:4570;
              proxy_http_version 1.1;
              proxy_set_header Upgrade $http_upgrade;
              proxy_set_header Connection 'upgrade';
              proxy_set_header Host $host;
              proxy_cache_bypass $http_upgrade;
            }
    }

    我们可以通过Nginx作为反向代理轻松设置Nodejs应用程序。
    以下配置假定NodeJS应用程序在127.0.0.1:8080上运行,

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
      server{
         server_name domain.com sub.domain.com; # multiple domains

         location /{
          proxy_pass http://127.0.0.1:8080;  
          proxy_set_header Host $host;
          proxy_pass_request_headers on;  
         }

         location /static/{
           alias /absolute/path/to/static/files; # nginx will handle js/css
         }
       }

    在上面设置你的Nodejs应用程序,

    • 获取HTTP_HOST标头,您可以在其中应用特定于域的逻辑来提供响应。"
    • 您的应用程序必须由pm2或主管等流程管理器管理,以处理情况/重用套接字或资源等。

    • 设置错误报告服务以获取诸如sentry或rollbar之类的生产错误

    注意:您可以设置用于处理特定于域的请求路由的逻辑,为expressjs应用程序创建中间件


    您还可以使用node.js将静态文件生成到nginx提供的目录中。当然,站点的某些动态部分可以由节点提供,有些则由nginx(静态)提供。

    其中一些由nginx提供服务可以提高您的性能。


    Nginx可以充当反向代理服务器,就像项目经理一样工作。当它收到请求时,它会分析它并将请求转发给上游(项目成员)或处理自己。 Nginx有两种基于配置方式处理请求的方法。

    • 满足要求
    • 将请求转发给另一台服务器

      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      12
      server{
       server_name mydomain.com sub.mydomain.com;

       location /{
        proxy_pass http://127.0.0.1:8000;  
        proxy_set_header Host $host;
        proxy_pass_request_headers on;  
       }

       location /static/{
         alias /my/static/files/path;
       }

      }

    服务器请求

    With this configuration, when the request url is
    mydomain.com/static/myjs.js it returns the myjs.js file in
    /my/static/files/path folder. When you configure nginx to serve
    static files, it handles the request itself.

    将请求转发给另一台服务器

    When the request url is mydomain.com/dothis nginx will forwards the
    request to http://127.0.0.1:8000. The service which is running on the
    localhost 8000 port will receive the request and returns the response
    to nginx and nginx returns the response to the client.

    当您在端口8000上运行node.js服务器时,nginx会将请求转发给node.js.编写node.js逻辑并处理请求。那就是你在nginx服务器后面运行你的nodejs服务器。

    如果你想运行除nodejs之外的任何其他服务,只需在不同的端口上运行另一个服务,如Django,flask,php,并在nginx中配置它。


    如果要管理每个微服务方式并运行它,可以使用pm2运行nodejs。节点将在端口中运行,只需在nginx中配置该端口(/etc/nginx/sites-enabled/domain.com)

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    server{
        listen 80;
        server_name domain.com www.domain.com;

      location / {
         return 403;
      }
        location /url {
            proxy_pass http://localhost:51967/info;
        }
    }

    使用ping检查localhost是否正在运行。

    1
    Create one single Node.js server which handles all Node.js requests. This reads the requested files and evals their contents. So the files are interpreted on each request, but the server logic is much simpler.

    这是最好的,正如你所说的那样容易