11

Node.js + Nginx - Что делать дальше?

19

У меня настроены Node.js и Nginx на сервере, и теперь я хочу начать их использовать, но у меня есть два вопроса:

  1. Как правильно организовать взаимодействие между Node.js и Nginx? Как мне следует обрабатывать запросы?

  2. Существуют два подхода к созданию сервера на Node.js. Какой из них лучше:

    1. Создать отдельный HTTP-сервер для каждого сайта, который в этом нуждается, и загружать весь JavaScript-код в начале программы, чтобы код интерпретировался один раз.
    2. Создать один единственный сервер на Node.js, который будет обрабатывать все запросы. Этот сервер будет считывать запрашиваемые файлы и выполнять их содержимое, что означает, что файлы интерпретируются при каждом запросе, но логика сервера значительно упрощается.

Мне не совсем ясно, как правильно использовать Node.js в этом контексте.

5 ответ(ов)

1

Вы также можете настроить несколько доменов с помощью Nginx, перенаправляющих на несколько процессов Node.js.

Например, чтобы добиться следующего:

  • domain1.example —> на процесс Node.js, работающий локально по адресу http://127.0.0.1:4000
  • domain2.example —> на процесс Node.js, работающий локально по адресу http://127.0.0.1:5000

Эти порты (4000 и 5000) должны быть использованы для прослушивания запросов к вашему приложению в вашем коде.

/etc/nginx/sites-enabled/domain1

server {
    listen 80;
    listen [::]:80;
    server_name domain1.example;
    access_log /var/log/nginx/domain1.access.log;
    location / {
        proxy_pass    http://127.0.0.1:4000/;
    }
}

/etc/nginx/sites-enabled/domain2

server {
    listen 80;
    listen [::]:80;
    server_name domain2.example;
    access_log /var/log/nginx/domain2.access.log;
    location / {
        proxy_pass    http://127.0.0.1:5000/;
    }
}

После внесения изменений не забудьте перезагрузить Nginx для применения новой конфигурации:

sudo systemctl reload nginx

Это позволит Nginx корректно направлять запросы на соответствующие процессы Node.js в зависимости от указанного домена.

0

Вы также можете настроить разные URL для приложений в одной конфигурации сервера:

  • yourdomain.example/app1/* перенаправляется на локальный процесс Node.js
    http://127.0.0.1:3000
  • yourdomain.example/app2/* перенаправляется на локальный процесс Node.js
    http://127.0.0.1:4000

В файле /etc/nginx/sites-enabled/yourdomain добавьте следующее:

server {
    listen 80;
    listen [::]:80;
    server_name yourdomain.example;

    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:

sudo service nginx restart

Запустите приложения:

app1.js

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

app2.js

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

Эта конфигурация позволит вам использовать разные маршруты для различных приложений, работающих на одном сервере.

0

Я проксирую независимые приложения на Node Express через Nginx. Это позволяет легко монтировать новые приложения и запускать другие сервисы на том же сервере, используя разные локации.

Вот детали моей настройки с примером конфигурации Nginx:

Развертывание нескольких приложений Node на одном веб-сервере в подпапках с помощью Nginx

Когда дело доходит до переноса вашего приложения с localhost в интернет, ситуация становится непростой. Нет единого подхода к развертыванию Node-приложений.

В интернете можно найти множество статей по этой теме, однако мне было сложно найти подходящее решение для моей настройки.

В целом, у меня есть веб-сервер, и я хочу, чтобы приложения Node были смонтированы в подпапки (например, http://myhost/demo/pet-project/), не внося при этом никаких зависимостей в код приложения. При этом мне нужно, чтобы на том же сервере работали и другие сервисы, например, блог.

Звучит просто, не правда ли? На самом деле, это не так просто.

Во многих примерах на вебе приложения Node либо работают на порту 80, либо проксируются Nginx на корень. Несмотря на то, что оба подхода действительны для определенных случаев, они не соответствуют моим простым, но немного экзотическим критериям.

Именно поэтому я создал свою конфигурацию Nginx, вот её отрывок:

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

Из этого примера вы можете заметить, что я смонтировал свое Node-приложение Pet Project, которое работает на порту 3000, по адресу http://myhost/demo/pet-project.

Сначала Nginx проверяет, является ли запрашиваемый ресурс статическим файлом, доступным по пути /opt/demo/pet-project/public/. Если да, то он просто отдает его, что значительно повышает эффективность, и нам не нужно добавлять слой вроде Connect static middleware.

Затем все другие запросы перезаписываются и проксируются в приложение Pet Project, поэтому Node-приложение не должно знать, где оно фактически смонтировано, и его можно перемещать в любом месте только путем изменения конфигурации.

proxy_redirect обязателен для правильной обработки заголовка Location. Это крайне важно, если вы используете res.redirect() в вашем приложении на Node.

Вы можете легко воспроизвести эту настройку для нескольких приложений Node, работающих на разных портах, и добавить больше обработчиков локаций для других нужд.

0

Для настройки Nginx в качестве обратного прокси для Node.js приложения, работающего на порту 3000, выполните следующие шаги:

  1. Откройте файл конфигурации для вашего поддомена с помощью команды:

    $ sudo nano /etc/nginx/sites-available/subdomain.your-domain.example
    
  2. Добавьте следующую конфигурацию в файл:

    upstream subdomain.your-domain.example {
      server 127.0.0.1:3000;
    }
    
    server {
      listen 80;
      listen [::]:80;
      server_name subdomain.your-domain.example;
    
      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-Forwarded-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.example;
        proxy_redirect off;
      }
    }
    
  3. Не забудьте активировать сайт, создав символическую ссылку в директории sites-enabled:

    $ sudo ln -s /etc/nginx/sites-available/subdomain.your-domain.example /etc/nginx/sites-enabled/
    
  4. Проверьте конфигурацию Nginx на наличие ошибок:

    $ sudo nginx -t
    
  5. Перезагрузите Nginx, чтобы применить изменения:

    $ sudo systemctl restart nginx
    

Теперь Nginx должен правильно перенаправлять весь трафик, приходящий на subdomain.your-domain.example, к вашему приложению Node.js, работающему на порту 3000.

0

В ответ на ваш вопрос 2:

Я бы выбрал вариант b, так как он потребляет значительно меньше ресурсов. Вариант a заставляет сервер расходовать много памяти, поскольку каждый клиент вызывает загрузку всех необходимых файлов (хоть мне и нравится PHP, это одна из его проблем). С вариантом b вы можете загружать свои библиотеки (переиспользуемый код) и делиться ими между всеми клиентскими запросами.

Но учтите, что если у вас несколько ядер, вам стоит настроить node.js для их использования.

Чтобы ответить на вопрос, пожалуйста, войдите или зарегистрируйтесь