Aynı Sunucuda Apache ve Node.js


352

Düğümü kullanmak istiyorum çünkü hızlı, istemci tarafında kullandığım dili kullanıyor ve tanım gereği engellemiyor. Ama dosya işleme (kaydetme, düzenleme, yeniden adlandırma, indirme, dosya yükleme, vb.) İçin programı yazmak için kiraladığım adam, apache kullanmak istiyor. Yani, yapmalıyım:

  1. Onu Düğüm'ü kullanmaya ikna et (bu konuda çok az şey bırakıyor)

  2. Düğüme dosya yükleme, indirme, yeniden adlandırma, kaydetme vb.

  3. Aynı sunucuya apache ve düğüm kurmalıyım.

En uygun durum hangisidir ve bunu nasıl uygularım?

Yanıtlar:


704

Harika bir soru!

PHP'de Apache üzerinde çalışan birçok web sitesi ve ücretsiz web uygulaması var, birçok insan bunu kullanıyor, böylece oldukça kolay bir şeyleri ezebiliyorsunuz ve ayrıca statik içerik sunmanın zekice bir yolu yok. Düğüm hızlı, güçlü, zarif ve V8'in ham gücü ve dahili bağımlılıkları olmayan düz bir yığını olan seksi bir araçtır.

Ayrıca Apache'nin kolaylığını / esnekliğini ve yine de Node.JS'nin homurdanmasını ve zarafetini istiyorum, neden her ikisine de sahip olamıyorum ?

Neyse ki Apache'deki ProxyPass yönergesi ile httpd.confNode.JS uygulamanıza belirli bir URL üzerindeki tüm istekleri iletmek çok zor değil.

ProxyPass /node http://localhost:8000

Ayrıca, http isteklerini yeniden yönlendirmek için doğru proxy'yi ve alt modülü almak için aşağıdaki satırların yorumlanmadığından emin olun:

LoadModule proxy_module modules/mod_proxy.so
LoadModule proxy_http_module modules/mod_proxy_http.so

Daha sonra Node uygulamanızı port 8000'de çalıştırın!

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');

Daha sonra URL'nizdeki /node/yolu kullanarak tüm Node.JS mantığına erişebilirsiniz , web sitesinin geri kalanı mevcut PHP sayfalarınızı barındırmak için Apache'ye bırakılabilir:

resim açıklamasını buraya girin

Şimdi geriye kalan tek şey hosting şirketinizi bu konfigürasyon ile koşturmanıza ikna etmek !!!


6
Bu harika bir cevaptı, sadece bu işi yapmak için kullandığım proxy geçişinde biraz daha fazla bilgi içeren bir bağlantı eklemek istedim. Yorumları da kontrol edin. boriskuzmanovic.wordpress.com/2006/10/20/…
Alex Muro

11
"ProxyPass / 127.0.0.1:8000 " bir sanal ana kapsayıcı içine koyarak test ve başarıyla tüm etki alanı grubu bir düğüm örneğine yeniden yönlendirmek mümkün. Ayrıca doğrudan Apache üzerinden erişime düğüm erişim hızını karşılaştırmak için "zaman wget ..." ile test. 30 çift denemede ortalama fark yaklaşık 0.56 ms idi. En düşük yükleme süresi hem doğrudan hem de Apache üzerinden 120 ms idi. En yüksek yükleme süresi doğrudan 154ms ve Apache üzerinden 164 idi. Önemli bir fark yok. İki IP lüksüne sahip olsaydım Apache'den geçemezdim, ama şimdilik Proxypass ile devam edeceğim
kaan_a

5
Bu vekil, Düğüm'ün engellemeyen doğasının faydalarını ortadan kaldırırken Apache'den Düğüm'e istemiyor mu?
İz

2
Merhaba @Basj, kendimi websockets için destek yükleme deneyimim yok. Bununla birlikte, Apache 2.4.6'nın websockets trafiğini kullanarak proxy yapmak için desteği olduğu görülüyor mod_proxy_wstunnel. Cevabınızı şimdi bulduğunuzu görüyorum, aynı sorunu olan diğerleri için lütfen şu adrese bakın: serverfault.com/questions/616370/…
Steven de Salas

4
Debian tabanlı dağıtımlara nereden ekleyebilirim? Httpd.conf dosyası yok.
santi

63

Bu soru daha fazla Sunucu Hatası'na aittir, ancak FWIW, Apache'nin Node.js önünde çalıştırılmasının çoğu durumda iyi bir yaklaşım olmadığını söyleyebilirim.

Apache'nin ProxyPass'ı birçok şey için harika (Tomcat tabanlı hizmetleri bir sitenin parçası olarak göstermek gibi) ve Node.js uygulamanız sadece belirli, küçük bir rol yapıyorsa veya yalnızca sınırlı sayıda kullanıcısı olan dahili bir araçsa sadece kullanmak daha kolay olabilir, böylece çalıştırabilir ve devam edebilirsiniz, ancak buradaki gibi görünmüyor.

Node.js'yi kullanarak elde edebileceğiniz performans ve ölçekten yararlanmak istiyorsanız ve özellikle web soketleri gibi kalıcı bir bağlantıyı sürdürmeyi içeren bir şey kullanmak istiyorsanız - hem Apache'yi hem de Düğümünüzü çalıştırmaktan daha iyi olursunuz. js diğer bağlantı noktalarında (örn. localhost üzerinde Apache: 8080, localhost üzerinde Node.js: 3000) ve daha sonra nginx, Vernik veya HA proxy gibi bir şey çalıştırıyor ve trafiği bu şekilde yönlendiriyor.

Vernik veya nginx gibi bir yolla trafiği yola ve / veya ana bilgisayara göre yönlendirebilirsiniz. Her ikisi de çok daha az sistem kaynağı kullanıyor ve aynı şeyi yapmak için Apache'yi kullanmaktan çok daha ölçeklenebilir.


13
bu cevabın daha fazla oyu olmalı. nginx proxy kullanmak apache olandan çok daha iyi bir yaklaşımdır.
rerich

Ya ama kaynak yoğun
Oracle

1
İfadenizi yedeklemek için nginx'in httpd'den daha az kaynak yoğun olacağı konusunda bazı rakamlarınız var mı?
RedShift

Oldukça dramatik olmama rağmen. Bağlantılarda kırılgan olduğu için yanıtlarda bağlantı oluşturmamaya çalışsam da , Google üzerinden bazı tartışmalar ve örnekler bulabilirsiniz - örneğin, help.dreamhost.com/hc/en-us/articles/…… Apache harika bir yazılımdır, ancak genellikle böyle bir bağlamda harika bir yaklaşım.
Iain Collins

Bu cevap kulağa hoş geliyor, ama sonra zaten Apache tarafından alındığı için Node.js'ye httpS üzerinden nasıl erişilir?
Pierre

34


Talimatlar çalıştırmak için node serverbirlikte apache2(v2.4.xx) server:

oluşturun node.js uygulamaya boru amacıyla belirli bir URL üzerinde tüm istekleri CUSTOM.confiçindeki dosyayı /etc/apache2/conf-availableoluşturdu dosyaya hattı aşağıdaki dizinde ve ekleyin:

ProxyPass /node http://localhost:8000/

8000'i için tercih edilen port numarasına değiştirin node server.
Aşağıdaki komutlarla özel yapılandırmaları etkinleştirin:

$> sudo a2enconf CUSTOM

CUSTOM, uzantısız yeni oluşturulan dosya adınızdır, daha sonra proxy_httpşu komutla etkinleştirin :

$> sudo a2enmod proxy_http

hem imkan vermelidir proxyve proxy_httpmodülleri. Modülün etkin olup olmadığını aşağıdakilerle kontrol edebilirsiniz:

$> sudo a2query -m MODULE_NAME

Yapılandırma ve modüller etkinleştirildikten sonra apache sunucusunu yeniden başlatmanız gerekir:

$> sudo service apache2 restart

Artık düğüm sunucusunu yürütebilirsiniz. Tüm istekleri URL/nodedüğüm sunucusu tarafından gerçekleştirilecektir.


Tıkır tıkır çalışıyor! :)
Kees Koenen

15

Düğüm ve Apache'yi tek bir sunucuda çalıştırmak, çakışmadığından önemsizdir. NodeJS, JavaScript sunucu tarafını yürütmenin bir yoludur. Gerçek ikilem, hem Düğüme hem de Apache'ye dışarıdan erişmekten gelir. Gördüğüm gibi iki seçeneğiniz var:

  1. Apache'yi, eşleşen tüm dosyaları NodeJS'ye proxy yapacak şekilde ayarlayın;

  2. Farklı IP'de Apache ve Düğüme sahip olun: bağlantı noktası kombinasyonları (sunucunuzda iki IP varsa, biri düğüm dinleyicinize, diğeri Apache'ye bağlanabilir).

Ben de bunun aslında aradığınız şey olmadığını düşünmeye başlıyorum. Nihai hedefiniz, uygulama mantığınızı Nodejs'e ve bir yükleniciye yüklediğiniz bazı "dosya işleme" bölümüne yazmaksa, o zaman gerçekten bir dil seçimi, bir web sunucusu değil.


9

Hem apache hem de diğer tüm nodejs uygulamalarını proxy yapmak için nodejs ile ters proxy sunucu yazma gibi farklı bir yaklaşım kullanabilirsiniz.

Öncelikle apache'nin 80 numaralı bağlantı noktasından farklı bir bağlantı noktasında çalıştırılması gerekir. Örn: 8080 numaralı bağlantı noktası

Sonra nodejs ile bir ters proxy komut dosyası yazabilirsiniz:

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");

Aşağıdaki makale bunu yapma sürecini açıklamaktadır.

NODE JS TERS PROXY İLE ÇALIŞMA APACHE - REDBIRD KULLANIMI


2
ProxyPass /node http://localhost:8000/     
  • httpd.conf yerine httpd-vhosts.conf dosyasına giriş yaptığımda bu benim için çalıştı
  • Çevremde yüklü XAMPP var & NodeJS uygulama 8080 bağlantı noktası üzerinde çalışan http: // localhost / [name_of_the_node_application] ile bağlantı noktası 80 apache tüm trafiği vurmak istiyordu

1

Yukarıdaki cevabı certbot SSL sertifikası ve CORS erişim-kontrol-izin-başlıkları ile birleştirdim ve çalıştırarak sonuçları paylaşacağımı düşündüm.

Apache httpd.conf dosyanın altına eklendi:

LoadModule proxy_module modules/mod_proxy.so
LoadModule proxy_http_module modules/mod_proxy_http.so

Apache VirtualHost ayarları (PHP için doc root Certbot ile Apache ve SSL altındadır, node.js / socket.io sitesi 3000 numaralı bağlantı noktasında çalışır ve Apache'den SSL sertifikası kullanır) Ayrıca node.js sitesinin klasör için proxy kullandığını da unutmayın. / nodejs, socket.io ve ws (websockets):

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

Sonra node.js uygulamam (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});

Bir ip4 dinleyicisini zorlarım, ancak bu isteğe bağlıdır - bunun yerine kullanabilirsiniz:

http.listen(3000);

node.js app (app.js) kodu şununla devam ediyor:

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...
});

son olarak, istemci tarafında (nodejs.js olarak yaratılmıştır):

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

Bu örnekte, JS yüklendiğinde, JSON'daki verileri node.js / socket.io sunucusuna gönderen bir "named-event" soketine yayılır.

Sunucudaki io ​​ve soketi path / nodejs (istemci tarafından bağlandı) altında kullanarak, verileri alır ve yayın olarak yeniden gönderir. Soketteki diğer kullanıcılar verileri dinleyicileri "isimli olay-yayın" ile alır. Gönderenin kendi yayınını almadığını unutmayın.


0

Geçenlerde bir PHP tabanlı codeigniter projesinde websocket kullanarak istemci ve sunucu arasında iletişim kurmak gerekir bu tür sorunu koştu.

Bağlantı noktalarını (çalışan düğüm uygulaması) Allow incoming TCP ports& Allow outgoing TCP portslistelere ekleyerek bu sorunu çözdüm.

Bu yapılandırmaları Firewall Configurationssunucunuzun WHM panelinde bulabilirsiniz.


-1

Aynı bilgiyi arıyordum. Sonunda @Straseus tarafından verilen cevaptaki bağlantıdan gelen cevabı buldum

http://arguments.callee.info/2010/04/20/running-apache-and-node-js-together/

Bağlantı noktası 80'de apache web sitesini, bağlantı noktası 8080'de düğüm js hizmetini çalıştırmak ve .htaccess RewriteRule kullanmak için son çözüm

Apache web sitesinin DocumentRoot'una aşağıdakileri ekleyin:

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]

Dizin düzeyi yönlendirme için yukarıdaki bağlantı, 'düğüm /' öğesinden sonra bir veya daha fazla karakter gerektiren önerilen (. +) Kuralını önerdi. İşlerimin çalışması için sıfır veya daha fazla olana (. *) Dönüştürmek zorunda kaldım.

@Straseus bağlantısı için çok teşekkürler


3
[P] bayrağının Apache'nin mod_proxyetkinleştirilmesini gerektirdiğini unutmayın.
Simon East

Bu verimsiz. Neden Yeniden Yazma motorunu bir basit üzerinden çağırmalısınız ProxyPass?
Michael Irigoyen

-2

Apache ve Düğüm'e atıfta bulunduğunuz için bir web uygulaması yaptığınızı varsayıyorum. Hızlı cevap - Mümkün - EVET. Tavsiye edilir - HAYIR. Düğüm kendi web sunucusu ve çoğu web sitesi 80 numaralı bağlantı noktasında çalışır. Şu anda Nodejs tarafından desteklenen hiçbir Apache eklentisi olmadığını ve sanal bir ana bilgisayar oluşturmanın bunu uygulamanın en iyi yolu olup olmadığından emin değilim. Bunlar, Nodejs'i Joyent'teki iyi insanlar gibi koruyan geliştiriciler tarafından cevaplanması gereken sorular.

Bağlantı noktaları yerine, Node'nun diğerlerinden tamamen farklı olan ve bu yüzden onu sevdiğim teknoloji yığınını değerlendirmek daha iyi olurdu, ancak önceden bilmeniz gereken birkaç uzlaşmayı da içerir.

Örneğiniz bir CMS veya bir paylaşım web uygulamasına benziyor ve Apache'de iyi çalışacak yüzlerce kullanıma hazır uygulama var. Hazır bir çözümden hoşlanmasanız bile, PHP / Java / Python'da bir web uygulaması yazabilir veya birkaç hazır uygulama ile eşleştirebilirsiniz ve hepsi tek bir Apache örneğinin arkasında çalışacak şekilde tasarlanmış ve desteklenmiştir.

Az önce söylediklerimi duraklatmanın ve düşünmenin zamanı geldi.

Şimdi hangi techstack'ı kullanacağınıza karar vermeye hazırsınız. Web siteniz Apache gerektiren binlerce hazır uygulamadan hiçbirini kullanmayacaksa, Düğüm için gidin, aksi takdirde daha önce belirttiğim varsayımları ortadan kaldırmalısınız.

Sonunda, techstack seçiminiz her bir bileşenden çok daha önemlidir.

@Straseus ile tamamen katılıyorum, yüklemeleri ve indirmeleri işlemek için node.js dosya sistemi API'sini kullanmanın nispeten önemsiz olduğunu, ancak uzun vadede web sitenizden ne istediğinizi daha fazla düşünün ve sonra techstack'ınızı seçin.

Düğümün çerçevesini öğrenmek diğer çerçeveleri öğrenmekten daha kolaydır, ancak her derde deva değildir. Biraz daha fazla çaba ile (bu kendi başına değerli bir çaba olabilir), başka herhangi bir çerçeveyi de öğrenebilirsiniz. Hepimiz birbirimizden öğreniyoruz ve küçük bir ekip olarak çalışıyorsanız, yalnız çalışıyorsanız ve arka uç teknik becerileriniz de daha hızlı gelişecektir. Bu nedenle, ekibinizin diğer üyelerinin becerilerini çok ucuza indirmeyin.

Bu yazı yaklaşık bir yaşında ve zaten karar vermişsinizdir, ancak umarım rantımın benzer bir karardan geçen bir sonraki kişiye yardımcı olacaktır.

Okuduğunuz için teşekkürler.

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.