Apache и Node.js на одном сервере
Я хочу использовать Node, потому что он быстрый, использует тот же язык, который я использую на стороне клиента, и по определению неблокируемый. Но парень, которого я нанял написать программу для обработки файлов (сохранение, редактирование, переименование, загрузка, выгрузка файлов и т. Д.), Он хочет использовать apache. Итак, я должен:
Убедите его использовать Node (он отказывается от этого)
Узнайте, как загружать, загружать, переименовывать, сохранять и т. Д. Файлы в узле или
Я должен установить Apache и узел на одном сервере.
Какая ситуация наиболее благоприятная и как мне ее реализовать?
9 ответов
Отличный вопрос!
В PHP реализовано множество веб-сайтов и бесплатных веб-приложений, которые работают на Apache, многие используют его, чтобы вы могли сделать что-то довольно простое и, кроме того, это простой способ предоставления статического контента. Node - это быстрый, мощный, элегантный и привлекательный инструмент с мощным V8 и плоским стеком без встроенных зависимостей.
Я также хочу легкость / гибкость Apache и в то же время грубость и элегантность Node.JS, почему я не могу иметь и то и другое?
К счастью, с помощью директивы ProxyPass в Apache httpd.conf
не слишком сложно передать все запросы по определенному URL-адресу в ваше приложение Node.JS.
ProxyPass /node http://localhost:8000
Кроме того, убедитесь, что следующие строки НЕ закомментированы, чтобы вы получили правильный прокси и субмодуль для перенаправления http-запросов:
LoadModule proxy_module modules/mod_proxy.so
LoadModule proxy_http_module modules/mod_proxy_http.so
Затем запустите приложение Node на порту 8000!
var http = require('http');
http.createServer(function (req, res) {
res.writeHead(200, {'Content-Type': 'text/plain'});
res.end('Hello Apache!\n');
}).listen(8000, '127.0.0.1');
Затем вы можете получить доступ ко всей логике Node.JS, используя /node/
путь к вашему URL, остальная часть сайта может быть оставлена Apache для размещения ваших существующих страниц PHP:
Теперь осталось только убедить вашу хостинговую компанию позволить вам работать с этой конфигурацией!!!
Этот вопрос больше относится к отказу сервера, но FWIW я бы сказал, что запуск Apache перед Node.js не очень хороший подход в большинстве случаев.
ProxyPass от Apache отлично подходит для многих вещей (например, предоставление сервисов на основе Tomcat как части сайта), и если ваше приложение Node.js выполняет определенную небольшую роль или является внутренним инструментом, который может иметь ограниченное количество пользователей. тогда может быть проще просто использовать его, чтобы вы могли заставить его работать и двигаться дальше, но это не похоже на случай здесь.
Если вы хотите воспользоваться преимуществами производительности и масштабируемости, которые вы получите от использования Node.js - и особенно если вы хотите использовать что-то, что подразумевает поддержание постоянного соединения, например, веб-сокеты, - вам лучше использовать Apache и ваш Node. js на других портах (например, Apache на localhost:8080, Node.js на localhost:3000), а затем запускать что-то вроде прокси nginx, Varnish или HA впереди - и таким образом маршрутизировать трафик.
С помощью чего-то вроде лака или nginx вы можете маршрутизировать трафик в зависимости от пути и / или хоста. Они оба используют гораздо меньше системных ресурсов и гораздо более масштабируемы, чем Apache, чтобы сделать то же самое.
Инструкция по запуску node server
вместе apache2(v2.4.xx) server
:
Чтобы передать все запросы по определенному URL-адресу в приложение Node.JS, создайте CUSTOM.conf
файл внутри /etc/apache2/conf-available
и добавьте следующую строку в созданный файл:
ProxyPass /node http://localhost:8000/
Измените 8000 на предпочтительный номер порта для node server
,
Включите пользовательские конфигурации с помощью следующей команды:
$> sudo a2enconf CUSTOM
CUSTOM - это ваше вновь созданное имя файла без расширения, затем включите proxy_http
с помощью команды:
$> sudo a2enmod proxy_http
это должно включить оба proxy
а также proxy_http
модули. Вы можете проверить, включен ли модуль с помощью:
$> sudo a2query -m MODULE_NAME
После настройки и включения модулей вам нужно будет перезапустить сервер Apache:
$> sudo service apache2 restart
Теперь вы можете выполнить узел сервера. Все запросы к URL/node
будет обработан сервером узла.
Запуск Node и Apache на одном сервере тривиален, так как они не конфликтуют. NodeJS - это просто способ выполнить серверную часть JavaScript. Настоящая дилемма возникает из-за доступа к Node и Apache извне. На мой взгляд, у вас есть два варианта:
Настройте Apache на прокси всех соответствующих запросов к NodeJS, который будет выполнять загрузку файлов и все остальное в узле.
Установите Apache и Node на разные комбинации IP: порт (если у вашего сервера два IP-адреса, то один может быть связан с прослушивателем вашего узла, а другой - с Apache).
Я также начинаю подозревать, что это может быть не то, что вы на самом деле ищете. Если ваша конечная цель заключается в том, чтобы вы написали логику приложения на Nodejs и какую-то часть "обработки файлов", которую вы выгружаете подрядчику, тогда это действительно выбор языка, а не веб-сервер.
Вы можете использовать другой подход, такой как написание обратного прокси-сервера с nodejs для прокси как Apache, так и всех других приложений nodejs.
Во-первых, вам нужно настроить Apache на другой порт, отличный от порта 80. Например: порт 8080.
тогда вы можете написать скрипт обратного прокси с nodejs как:
var proxy = require('redbird')({port: 80, xfwd: false);
proxy.register("mydomain.me/blog", "http://mydomain.me:8080/blog");
proxy.register("mydomain.me", "http://mydomain.me:3000");
Следующая статья описывает весь процесс создания этого.
Я объединил приведенный выше ответ с сертификатом SSL certbot и заголовками CORS access-control-allow-headers и получил его, так что я подумал, что поделюсь результатами.
Apache httpd.conf добавлен в конец файла:
LoadModule proxy_module modules/mod_proxy.so
LoadModule proxy_http_module modules/mod_proxy_http.so
Настройки Apache VirtualHost (корень doc для PHP находится под Apache и SSL с Certbot, а сайт node.js/socket.io работает на порту 3000 - и использует сертификат SSL от Apache). Также обратите внимание, что сайт node.js использует прокси для папки / nodejs, socket.io и ws (веб-сокеты):
<IfModule mod_ssl.c>
<VirtualHost *:443>
ServerName www.example.com
ServerAlias www.example.com
DocumentRoot /var/html/www.example.com
ErrorLog /var/html/log/error.log
CustomLog /var/html/log/requests.log combined
SSLCertificateFile /etc/letsencrypt/live/www.example.com/fullchain.pem
SSLCertificateKeyFile /etc/letsencrypt/live/www.example.com/privkey.pem
Include /etc/letsencrypt/options-ssl-apache.conf
RewriteEngine On
RewriteCond %{REQUEST_URI} ^socket.io [NC]
RewriteCond %{QUERY_STRING} transport=websocket [NC]
RewriteRule /{.*} ws://localhost:3000/$1 [P,L]
RewriteCond %{HTTP:Connection} Upgrade [NC]
RewriteRule /(.*) ws://localhost:3000/$1 [P,L]
ProxyPass /nodejs http://localhost:3000/
ProxyPassReverse /nodejs http://localhost:3000/
ProxyPass /socket.io http://localhost:3000/socket.io
ProxyPassReverse /socket.io http://localhost:3000/socket.io
ProxyPass /socket.io ws://localhost:3000/socket.io
ProxyPassReverse /socket.io ws://localhost:3000/socket.io
</VirtualHost>
</IfModule>
Затем мое приложение node.js (app.js):
var express = require('express');
var app = express();
app.use(function(req, res, next) {
res.header("Access-Control-Allow-Origin", "*");
res.header("Access-Control-Allow-Headers", "X-Requested-With");
res.header("Access-Control-Allow-Headers", "Content-Type");
res.header("Access-Control-Allow-Methods", "PUT, GET, POST, DELETE, OPTIONS");
next();
});
var http = require('http').Server(app);
var io = require('socket.io')(http);
http.listen({host:'0.0.0.0',port:3000});
Я принудительно использую прослушиватель ip4, но это необязательно - вы можете заменить:
http.listen(3000);
Код приложения node.js (app.js) продолжается:
io.of('/nodejs').on('connection', function(socket) {
//optional settings:
io.set('heartbeat timeout', 3000);
io.set('heartbeat interval', 1000);
//listener for when a user is added
socket.on('add user', function(data) {
socket.join('AnyRoomName');
socket.broadcast.emit('user joined', data);
});
//listener for when a user leaves
socket.on('remove user', function(data) {
socket.leave('AnyRoomName');
socket.broadcast.emit('user left', data);
});
//sample listener for any other function
socket.on('named-event', function(data) {
//code....
socket.broadcast.emit('named-event-broadcast', data);
});
// add more listeners as needed... use different named-events...
});
наконец, на стороне клиента (созданной как nodejs.js):
//notice the /nodejs path
var socket = io.connect('https://www.example.com/nodejs');
//listener for user joined
socket.on('user joined', function(data) {
// code... data shows who joined...
});
//listener for user left
socket.on('user left', function(data) {
// code... data shows who left...
});
// sample listener for any function:
socket.on('named-event-broadcast', function(data) {
// this receives the broadcast data (I use json then parse and execute code)
console.log('data1=' + data.data1);
console.log('data2=' + data.data2);
});
// sample send broadcast json data for user joined:
socket.emit('user joined', {
'userid': 'userid-value',
'username':'username-value'
});
// sample send broadcast json data for user left
//(I added the following with an event listener for 'beforeunload'):
// socket.emit('user joined', {
// 'userid': 'userid-value',
// 'username':'username-value'
// });
// sample send broadcast json data for any named-event:
socket.emit('named-event', {
'data1': 'value1',
'data2':'value2'
});
В этом примере, когда JS загружается, он передает сокету "именованное событие", отправляя данные в формате JSON на сервер node.js/socket.io.
Используя io и сокет на сервере в path /nodejs (подключенном клиентом), получает данные и затем повторно отправляет их как широковещательную рассылку. Любые другие пользователи в сокете будут получать данные со своим слушателем "named-event-broadcast". Обратите внимание, что отправитель не получает собственную трансляцию.
ProxyPass /node http://localhost:8000/
- это сработало для меня, когда я сделал выше запись в httpd-vhosts.conf вместо httpd.conf
- Я установил XAMPP в своей среде и собирался поразить весь трафик на apache через порт 80 с приложением NodeJS, работающим на порту 8080, то есть http://localhost/[name_of_the_node_application]
Недавно я столкнулся с такой проблемой, когда мне нужно общаться между клиентом и сервером с помощью веб-сокета в проекте codeigniter на основе PHP.
Я решил эту проблему, добавив свой порт (запущенное приложение узла) в Allow incoming TCP ports
& Allow outgoing TCP ports
списки.
Вы можете найти эти конфигурации в Firewall Configurations
в панели WHM вашего сервера.
Я искал ту же информацию. Наконец-то нашел ответ по ссылке на ответ выше @Straseus
http://arguments.callee.info/2010/04/20/running-apache-and-node-js-together/
Вот окончательное решение для запуска веб-сайта apache на порту 80, службы узла js на порту 8080 и использования.htaccess RewriteRule
В DocumentRoot веб-сайта apache добавьте следующее:
Options +FollowSymLinks -MultiViews
<IfModule mod_rewrite.c>
RewriteEngine on
# Simple URL redirect:
RewriteRule ^test.html$ http://arguments.callee.info:8000/test/ [P]
# More complicated (the user sees only "benchmark.html" in their address bar)
RewriteRule ^benchmark.html$ http://arguments.callee.info:8000/node?action=benchmark [P]
# Redirect a whole subdirectory:
RewriteRule ^node/(.*) http://arguments.callee.info:8000/$1 [P]
Для перенаправления на уровне каталога, ссылка выше предложила (.+) Правило, для которого требуется один или несколько символов после "узла /". Я должен был преобразовать его в (.*), Который равен нулю или больше, чтобы мои вещи работали.
Большое спасибо за ссылку @Straseus
Я предполагаю, что вы делаете веб-приложение, потому что вы ссылаетесь на Apache и Node. Быстрый ответ - возможно ли это - ДА. Рекомендуется - НЕТ. Node объединяет свой собственный веб-сервер, и большинство веб-сайтов работают на порте 80. Я также предполагаю, что в настоящее время нет плагина Apache, который поддерживается Nodejs, и я не уверен, является ли создание виртуального хоста лучшим способом для реализации этого. На эти вопросы должны ответить разработчики, которые поддерживают Nodejs как хороших людей в Joyent.
Вместо портов было бы лучше оценить технический стек Node, который полностью отличается от большинства других, и именно поэтому я люблю его, но он также включает в себя несколько компромиссов, о которых вы должны знать заранее.
Ваш пример похож на CMS или веб-приложение для обмена, и есть сотни готовых приложений, которые будут отлично работать на Apache. Даже если вам не нравится какое-либо готовое решение, вы можете написать веб-приложение на PHP / Java / Python или смешать и сопоставить его с парой готовых приложений, и все они разработаны и поддерживаются для работы за одним экземпляром Apache.
Пришло время остановиться и подумать о том, что я только что сказал.
Теперь вы готовы решить, какой стэк вы собираетесь использовать. Если на вашем веб-сайте никогда не будут использоваться какие-либо из тысяч готовых приложений, для которых требуется Apache, то перейдите к Node, в противном случае вы должны сначала устранить предположения, которые я изложил ранее.
В конце концов, ваш выбор techstack гораздо важнее, чем любой отдельный компонент.
Я полностью согласен с @Straseus в том, что относительно просто использовать api файловой системы node.js для обработки загрузок и загрузок, но в будущем подумайте больше о том, что вы хотите от своего веб-сайта, а затем выберите свой технический стэк.
Изучение структуры Node проще, чем изучение других структур, но это не панацея. Приложив немного больше усилий (что само по себе может быть полезным), вы также можете изучить любую другую среду. Мы все учимся друг у друга, и вы будете более продуктивными, если будете работать небольшой командой, чем если вы работаете в одиночку, и ваши технические навыки бэкэнда также будут развиваться быстрее. Поэтому не стоит сбрасывать со счетов навыки других членов вашей команды так дешево.
Этому посту около года, и есть вероятность, что вы уже решили, но я надеюсь, что моя напыщенная речь поможет следующему человеку, который принимает подобное решение.
Спасибо за прочтение.
Вы можете установить оба на одном сервере, но они должны быть настроены для использования разных портов. Оба не могут использовать порт 80, по крайней мере, не так легко.
Имейте в виду, что Apache - это сервер, а nodeJS - это язык.
Вы пытались погуглить вопрос, прежде чем спросить здесь?
http://arguments.callee.info/2010/04/20/running-apache-and-node-js-together/
Что мне нужно для запуска сценария node.js на моем сервере?
http://www.readwriteweb.com/hack/2010/12/how-to-run-apache-and-nodejs.php