Apache dan Node.js di Server yang Sama

352

Saya ingin menggunakan Node karena cepat, menggunakan bahasa yang sama yang saya gunakan di sisi klien, dan itu bukan pemblokiran menurut definisi. Tetapi orang yang saya sewa untuk menulis program untuk penanganan file (menyimpan, mengedit, mengganti nama, mengunduh, mengunggah file, dll.), Dia ingin menggunakan apache. Jadi saya harus:

  1. Meyakinkan dia untuk menggunakan Node (dia menyerah sedikit pada itu)

  2. Cari tahu cara mengunggah, mengunduh, mengganti nama, menyimpan, dll. File dalam simpul atau

  3. Saya harus menginstal apache dan node di server yang sama.

Situasi mana yang paling menguntungkan, dan bagaimana saya menerapkannya?

Mat
sumber

Jawaban:

704

Pertanyaan bagus!

Ada banyak situs web dan aplikasi web gratis yang diimplementasikan dalam PHP yang berjalan di Apache, banyak orang menggunakannya sehingga Anda dapat menumbuhkan sesuatu yang cukup mudah dan selain itu, ini adalah cara yang tidak perlu untuk menyajikan konten statis. Node cepat, kuat, elegan, dan alat yang seksi dengan kekuatan mentah V8 dan tumpukan datar tanpa ketergantungan bawaan.

Saya juga menginginkan kemudahan / fleksibilitas dari Apache dan juga kegeraman dan keanggunan Node.JS, mengapa saya tidak memiliki keduanya ?

Untungnya dengan arahan ProxyPass di Apache httpd.conftidak terlalu sulit untuk mengirim semua permintaan pada URL tertentu ke aplikasi Node.JS Anda.

ProxyPass /node http://localhost:8000

Juga, pastikan baris berikut TIDAK dikomentari sehingga Anda mendapatkan proxy dan submodule yang tepat untuk mengubah rute permintaan http:

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

Kemudian jalankan aplikasi Node Anda di port 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');

Kemudian Anda dapat mengakses semua logika Node.JS menggunakan /node/jalur di url Anda, sisa situs web dapat diserahkan ke Apache untuk meng-host halaman PHP Anda yang ada:

masukkan deskripsi gambar di sini

Sekarang satu-satunya yang tersisa adalah meyakinkan perusahaan hosting Anda untuk menjalankannya dengan konfigurasi ini !!!

Steven de Salas
sumber
6
Ini adalah jawaban yang bagus, hanya ingin menambahkan tautan dengan sedikit info lebih lanjut tentang proxy pass yang saya gunakan untuk membuat pekerjaan ini. Periksa komentarnya juga. boriskuzmanovic.wordpress.com/2006/10/20/…
Alex Muro
11
Saya menguji menempatkan "ProxyPass / 127.0.0.1:8000 " di dalam wadah virtual host dan berhasil mengarahkan seluruh grup domain ke instance node. Saya juga diuji dengan "time wget ..." untuk membandingkan kecepatan mengakses node secara langsung untuk mengaksesnya melalui Apache. Dalam 30 pasang percobaan, perbedaan rata-rata adalah sekitar 0,56 ms. Waktu buka terendah adalah 120 ms untuk direct dan via Apache. Waktu buka tertinggi adalah 154ms untuk langsung dan 164 melalui Apache. Bukan perbedaan yang signifikan. Jika saya memiliki kemewahan dua IP, saya tidak akan merutekan Apache, tetapi untuk saat ini saya akan tetap menggunakan Proxypass
kaan_a
5
Bukankah proxy ini meminta dari Apache ke Node, sementara itu menghilangkan manfaat dari sifat non-blocking Node?
Lacak
2
Hai @ Basj, saya sendiri tidak punya pengalaman menginstal dukungan untuk websockets. Karena itu, Apache 2.4.6 tampaknya memiliki dukungan untuk proxy lalu lintas websockets dengan menggunakan mod_proxy_wstunnel. Saya melihat Anda sekarang telah menemukan jawaban Anda, untuk orang lain dengan masalah yang sama silakan merujuk ke: serverfault.com/questions/616370/…
Steven de Salas
4
Di mana saya menambahkan ini pada distribusi berbasis debian? Tidak ada file httpd.conf.
santi
63

Pertanyaan ini lebih pada Server Fault tetapi FWIW saya katakan menjalankan Apache di depan Node.js bukan pendekatan yang baik dalam banyak kasus.

ProxyPass dari Apache sangat luar biasa untuk banyak hal (seperti mengekspos layanan berbasis Tomcat sebagai bagian dari sebuah situs) dan jika aplikasi Node.js Anda hanya melakukan peran tertentu, kecil, atau merupakan alat internal yang cenderung memiliki jumlah pengguna yang terbatas maka mungkin lebih mudah hanya menggunakannya sehingga Anda bisa membuatnya bekerja dan melanjutkan, tetapi itu tidak terdengar seperti kasus di sini.

Jika Anda ingin memanfaatkan kinerja dan skala yang akan Anda dapatkan dari menggunakan Node.js - dan terutama jika Anda ingin menggunakan sesuatu yang melibatkan mempertahankan koneksi yang terus-menerus seperti soket web - Anda lebih baik menjalankan Apache dan Node Anda. js pada port lain (mis. Apache pada localhost: 8080, Node.js pada localhost: 3000) dan kemudian menjalankan sesuatu seperti nginx, Varnish atau proksi HA di depan - dan merutekan lalu lintas dengan cara itu.

Dengan sesuatu seperti pernis atau nginx Anda dapat merutekan lalu lintas berdasarkan path dan / atau host. Mereka berdua menggunakan sumber daya sistem yang jauh lebih sedikit dan jauh lebih scalable menggunakan Apache untuk melakukan hal yang sama.

Iain Collins
sumber
13
jawaban ini seharusnya memiliki lebih banyak suara positif. itu jelas pendekatan yang jauh lebih baik untuk menggunakan nginx proxy daripada apache satu.
rerich
Ya tetapi ini adalah sumber daya yang intensif
Oracle
1
Apakah Anda memiliki beberapa nomor untuk mendukung pernyataan Anda bahwa nginx akan lebih sedikit sumber daya daripada httpd?
RedShift
Saya tidak berpikir itu cukup dramatis. Walaupun saya mencoba untuk tidak menautkan balasan karena tautan itu rapuh tetapi Anda dapat menemukan beberapa diskusi dan contoh melalui Google - mis. Help.dreamhost.com/hc/en-us/articles/… ... Apache adalah perangkat lunak yang hebat tetapi biasanya itu bukan pendekatan hebat dalam konteks seperti ini.
Iain Collins
Jawaban ini kedengarannya bagus, tetapi kemudian bagaimana mengakses Node.js melalui http karena sudah diambil oleh Apache?
Pierre
34


Instruksi untuk menjalankan node serverbersama apache2(v2.4.xx) server:

Dalam rangka untuk pipa semua permintaan pada URL tertentu untuk aplikasi Node.js Anda membuat CUSTOM.conffile di /etc/apache2/conf-availabledirektori, dan tambahkan baris berikut ke file yang dibuat:

ProxyPass /node http://localhost:8000/

Ubah 8000 ke nomor port yang diinginkan untuk node server.
Aktifkan konfigurasi khusus dengan perintah berikut:

$> sudo a2enconf CUSTOM

CUSTOM adalah nama file Anda yang baru dibuat tanpa ekstensi, kemudian aktifkan proxy_httpdengan perintah:

$> sudo a2enmod proxy_http

harus mengaktifkan modul proxydan keduanya proxy_http. Anda dapat memeriksa apakah modul diaktifkan atau tidak dengan:

$> sudo a2query -m MODULE_NAME

Setelah konfigurasi dan modul diaktifkan, Anda harus memulai ulang server apache:

$> sudo service apache2 restart

Sekarang Anda dapat menjalankan server simpul. Semua permintaan ke URL/nodeakan ditangani oleh server simpul.

krmld
sumber
Bekerja seperti pesona! :)
Kees Koenen
15

Menjalankan Node dan Apache pada satu server sepele karena mereka tidak konflik. NodeJS hanyalah cara untuk mengeksekusi sisi server JavaScript. Dilema sesungguhnya datang dari mengakses Node dan Apache dari luar. Seperti yang saya lihat, Anda memiliki dua pilihan:

  1. Siapkan Apache untuk mem-proksi semua permintaan yang cocok ke NodeJS, yang akan melakukan pengunggahan file dan apa pun lainnya dalam node.

  2. Memiliki Apache dan Node pada kombinasi IP: port yang berbeda (jika server Anda memiliki dua IP, maka satu dapat terikat ke pendengar simpul Anda, yang lain ke Apache).

Saya juga mulai curiga bahwa ini mungkin bukan yang sebenarnya Anda cari. Jika tujuan akhir Anda adalah untuk menulis logika aplikasi Anda di Nodejs dan beberapa bagian "penanganan file" yang Anda lepas ke kontraktor, maka itu benar-benar pilihan bahasa, bukan server web.

Yarek T
sumber
9

Anda dapat menggunakan pendekatan yang berbeda seperti menulis server proxy terbalik dengan nodejs untuk mem-proksi apache dan semua aplikasi nodejs lainnya.

Pertama, Anda perlu menjalankan apache di port lain selain port 80. mis: port 8080

Kemudian Anda dapat menulis skrip proxy terbalik dengan nodejs sebagai:

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

Artikel berikut menjelaskan keseluruhan proses pembuatan ini.

LARI APACHE DENGAN NODE JS REVERSE PROXY - MENGGUNAKAN REDBIRD

wathmal
sumber
2
ProxyPass /node http://localhost:8000/     
  • ini bekerja untuk saya ketika saya membuat entri di atas di httpd-vhosts.conf bukan httpd.conf
  • Saya telah menginstal XAMPP di lingkungan saya & ingin memukul semua lalu lintas di apache pada port 80 dengan NodeJS applicatin berjalan pada port 8080 yaitu http: // localhost / [name_of_the_node_application]
rahul shukla
sumber
1

Saya menggabungkan jawaban di atas dengan certbot SSL cert dan CORS access-control-allow-header dan membuatnya berfungsi sehingga saya pikir saya akan membagikan hasilnya.

Apache httpd.conf ditambahkan ke bagian bawah file:

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

Pengaturan VirtualHost Apache (root doc untuk PHP berada di bawah Apache dan SSL dengan Certbot, sementara situs node.js / socket.io berjalan pada port 3000 - dan menggunakan sertifikat SSL dari Apache) Juga perhatikan situs node.js menggunakan proxy untuk folder / nodejs, socket.io, dan 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>

Maka aplikasi node.js saya (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});

Saya memaksa pendengar ip4, tapi itu opsional - Anda bisa mengganti:

http.listen(3000);

kode app node.js (app.js) berlanjut dengan:

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

akhirnya, di sisi klien (dibuat sebagai 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'
});

Dalam contoh ini ketika JS dimuat, ia akan memancarkan "peristiwa-bernama" ke soket mengirim data dalam JSON ke server node.js / socket.io.

Menggunakan io dan soket pada server di bawah jalur / nodejs (terhubung oleh klien), menerima data dan kemudian mengirimkannya kembali sebagai siaran. Setiap pengguna lain dalam soket akan menerima data dengan pendengar mereka "bernama-acara-siaran". Perhatikan bahwa pengirim tidak menerima siarannya sendiri.

Aaron Dishno
sumber
0

Saya baru-baru ini mengalami masalah ini, di mana saya perlu berkomunikasi antara klien dan server menggunakan websocket dalam proyek codeigniter berbasis PHP.

Saya menyelesaikan masalah ini dengan menambahkan port saya (aplikasi node aktif) ke Allow incoming TCP ports& Allow outgoing TCP portsdaftar.

Anda dapat menemukan konfigurasi ini di Firewall Configurationspanel WHM server Anda.

Paritosh Pandey
sumber
-1

Saya mencari informasi yang sama. Akhirnya ditemukan jawaban dari tautan pada jawaban di atas oleh @ Straseus

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

Berikut adalah solusi terakhir untuk menjalankan situs web apache pada port 80, layanan simpul js pada port 8080 dan menggunakan .htaccess RewriteRule

Di DocumentRoot situs web apache, tambahkan berikut ini:

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]

Untuk pengalihan tingkat direktori, tautan di atas menyarankan (. +) Aturan, yang memerlukan satu atau lebih karakter setelah 'simpul /'. Saya harus mengonversikannya ke (. *) Yang nol atau lebih agar barang saya berfungsi.

Terima kasih banyak untuk tautannya @ Straseus

pd1980
sumber
3
Harap perhatikan bahwa bendera [P] mengharuskan Apache mod_proxydiaktifkan.
Simon East
Ini tidak efisien. Mengapa meminta mesin Menulis Ulang lebih sederhana ProxyPass?
Michael Irigoyen
-2

Saya berasumsi bahwa Anda membuat aplikasi web karena Anda merujuk ke Apache dan Node. Jawaban cepat - Apakah mungkin - YA. Apakah disarankan - TIDAK. Node bundel itu adalah server web sendiri dan sebagian besar situs web berjalan pada port 80. Saya juga berasumsi bahwa saat ini tidak ada plugin Apache yang didukung oleh Nodejs dan saya tidak yakin apakah membuat virtual host adalah cara terbaik untuk mengimplementasikannya. Ini adalah pertanyaan yang harus dijawab oleh pengembang yang memelihara Nodejs seperti orang-orang baik di Joyent.

Daripada port, akan lebih baik untuk mengevaluasi tumpukan teknologi Node yang benar-benar berbeda dari kebanyakan orang lain dan itulah sebabnya saya menyukainya tetapi itu juga melibatkan beberapa kompromi yang harus Anda ketahui sebelumnya.

Contoh Anda terlihat mirip dengan CMS atau aplikasi web berbagi dan ada ratusan aplikasi di luar kotak yang tersedia yang akan berjalan dengan baik di Apache. Bahkan jika Anda tidak menyukai solusi readymade, Anda bisa menulis webapp dalam PHP / Java / Python atau mencampur dan mencocokkannya dengan beberapa aplikasi siap pakai dan semuanya dirancang dan didukung untuk berjalan di belakang satu instance Apache.

Sudah waktunya untuk berhenti dan memikirkan apa yang baru saja saya katakan.

Sekarang Anda siap untuk memutuskan techstack mana yang akan Anda gunakan. Jika situs web Anda tidak akan pernah menggunakan salah satu dari ribuan aplikasi siap pakai yang memerlukan Apache, maka pilih Node jika tidak, Anda harus terlebih dahulu menghilangkan asumsi yang telah saya sebutkan sebelumnya.

Pada akhirnya, pilihan techstack Anda jauh lebih penting daripada komponen individu mana pun.

Saya sepenuhnya setuju dengan @ Straseus bahwa itu relatif sepele untuk menggunakan api sistem file node.js untuk menangani unggahan dan unduhan tetapi berpikir lebih banyak tentang apa yang Anda inginkan dari situs web Anda dalam jangka panjang dan kemudian memilih techstack Anda.

Mempelajari kerangka kerja Node lebih mudah daripada mempelajari kerangka kerja lain tetapi itu bukan obat mujarab. Dengan upaya yang sedikit lebih (yang mungkin merupakan upaya yang berharga dalam dirinya sendiri), Anda dapat mempelajari kerangka kerja lainnya juga. Kita semua belajar dari satu sama lain dan Anda akan lebih produktif jika Anda bekerja sebagai tim kecil daripada jika Anda bekerja sendiri dan keterampilan teknis backend Anda juga akan berkembang lebih cepat. Karena itu, jangan mengabaikan keahlian anggota tim Anda dengan harga murah.

Posting ini berumur sekitar satu tahun dan kemungkinan Anda sudah memutuskan, tetapi saya harap kata-kata kasar saya akan membantu orang berikutnya yang sedang mengalami keputusan serupa.

Terima kasih sudah membaca.

RHT
sumber