Node.js“ เซิร์ฟเวอร์” เปรียบเทียบกับเซิร์ฟเวอร์ Nginx หรือ Apache อย่างไร


90

ฉันเพิ่งศึกษา Node.js เมื่อไม่นานมานี้และพบเนื้อหาบางอย่างเกี่ยวกับการเขียนเซิร์ฟเวอร์ที่ใช้ Node.js อย่างง่าย ตัวอย่างเช่นต่อไปนี้

var express = require("express"),
http = require("http"), app;

// Create our Express-powered HTTP server
// and have it listen on port 3000
app = express();
http.createServer(app).listen(3000);

// set up our routes
app.get("/hello", function (req, res) {
    res.send("Hello World!");
});

app.get("/goodbye", function (req, res) {
    res.send("Goodbye World!");
});

ถึงแม้ว่าฉันจะเข้าใจว่าเกิดอะไรขึ้นในโค้ด แต่ฉันก็สับสนกับคำศัพท์เล็กน้อย เมื่อฉันได้ยินคำว่าเซิร์ฟเวอร์ฉันคิดถึงสิ่งต่างๆเช่น Apache หรือ Nginx ฉันเคยคิดเกี่ยวกับพวกเขาว่าเป็นเหมือนคอนเทนเนอร์ที่สามารถเก็บแอปพลิเคชันเว็บของฉันได้ เซิร์ฟเวอร์ Node.js แตกต่างจากเซิร์ฟเวอร์ Nginx / Apache อย่างไร? เป็นความจริงหรือไม่ที่เซิร์ฟเวอร์ที่ใช้ Node.js (เช่นรหัส) ยังสามารถวางไว้ในบางสิ่งเช่น Nginx เพื่อรัน เหตุใดทั้งสองจึงเรียกว่า "เซิร์ฟเวอร์"?


2
Isn't it true that a Node.js based server (i.e. code) will still be placed within something like Nginx to run?ไม่ถูกต้อง
Jaromanda X

1
ในทางเทคนิคคุณสามารถเรียกใช้แอปของคุณและมีโหนดที่ให้บริการแก่ลูกค้าเพื่อเติมเต็มบทบาทของเว็บเซิร์ฟเวอร์ได้อย่างมีประสิทธิภาพ แต่คุณอาจจะกัดมากกว่าที่คุณต้องการเคี้ยว ฉันเพิ่งอ่านบทความดีๆในหัวข้อนี้: nginx.com/blog/nginx-vs-apache-our-view
datafunk

1
ให้ฉันชี้แจงว่าเมื่อฉันขอความแตกต่างระหว่างทั้งสองฉันไม่ได้คำนึงถึง apache vs nginx ฉันใช้เกี่ยวกับ Node.js กับ Nginx
ขอบคุณ

1
อย่าปล่อยให้ชื่อทำให้คุณเข้าใจผิด หากคุณอ่านบทความนี้คุณจะเข้าใจว่าทำไมฉันถึงพูดในขณะที่คุณทำเองได้ แต่คุณอาจไม่ต้องการ ...
datafunk

คำตอบ:


132

มันเป็นเซิร์ฟเวอร์ใช่

เว็บแอปพลิเคชัน node.js เป็นเว็บเซิร์ฟเวอร์เต็มรูปแบบเช่นเดียวกับ Nginx หรือ Apache

คุณสามารถให้บริการแอปพลิเคชัน node.js ของคุณได้โดยไม่ต้องใช้เว็บเซิร์ฟเวอร์อื่น เพียงแค่เปลี่ยนรหัสของคุณเป็น:

app = express();
http.createServer(app).listen(80); // serve HTTP directly

อันที่จริงบางโปรเจ็กต์ใช้ node.js เป็นโหลดบาลานเซอร์ส่วนหน้าสำหรับเซิร์ฟเวอร์อื่น ๆ (รวมถึง Apache)

โปรดทราบว่า node.js ไม่ใช่สแต็กการพัฒนาเพียงอย่างเดียวที่ทำได้ กรอบการพัฒนาเว็บใน Go, Java และ Swift ก็ทำเช่นนี้เช่นกัน

ทำไม?

ในช่วงแรกคือ CGI CGI ดีและทำงานได้ดี Apache จะได้รับคำขอพบว่า url จำเป็นต้องเรียกใช้แอป CGI เรียกใช้แอป CGI นั้นและส่งผ่านข้อมูลเป็นตัวแปรสภาพแวดล้อมอ่าน stdout และให้บริการข้อมูลกลับไปที่เบราว์เซอร์

ปัญหาคือมันช้า เป็นเรื่องปกติเมื่อแอป CGI เป็นโปรแกรม C ที่คอมไพล์แบบคงที่ขนาดเล็ก แต่กลุ่มของโปรแกรม C ที่คอมไพล์แบบคงที่ขนาดเล็กนั้นยากที่จะรักษา ผู้คนจึงเริ่มเขียนด้วยภาษาสคริปต์ จากนั้นก็ยากที่จะรักษาและผู้คนก็เริ่มพัฒนาเฟรมเวิร์ก MVC เชิงวัตถุ ตอนนี้เราเริ่มมีปัญหา - ทุกคำขอจะต้องรวบรวมคลาสเหล่านั้นทั้งหมดและสร้างออบเจ็กต์เหล่านั้นทั้งหมดเพียงเพื่อให้บริการ HTML บางส่วนแม้ว่าจะไม่มีอะไรให้แสดงแบบไดนามิกก็ตาม (เนื่องจากเฟรมเวิร์กจำเป็นต้องพิจารณาว่าไม่มีอะไรที่จะให้บริการแบบไดนามิก)

จะเป็นอย่างไรหากเราไม่จำเป็นต้องสร้างวัตถุเหล่านั้นทุกคำขอ?

นั่นคือสิ่งที่ผู้คนคิด และจากการพยายามแก้ปัญหานั้นก็มีหลายกลยุทธ์ หนึ่งในสิ่งแรกสุดคือการฝังล่ามโดยตรงในเว็บเซิร์ฟเวอร์เช่นmod_phpใน Apache คลาสและอ็อบเจ็กต์ที่คอมไพล์สามารถเก็บไว้ในตัวแปรส่วนกลางดังนั้นจึงแคช อีกกลยุทธ์หนึ่งคือการรวบรวมข้อมูลล่วงหน้า และอีกกลยุทธ์หนึ่งคือการเรียกใช้แอปพลิเคชันเป็นกระบวนการเซิร์ฟเวอร์ปกติและพูดคุยกับเว็บเซิร์ฟเวอร์โดยใช้โปรโตคอลที่กำหนดเองเช่น FastCGI

จากนั้นนักพัฒนาบางคนก็เริ่มใช้ HTTP เป็นโปรโตคอลเซิร์ฟเวอร์ของแอป -> แอพนี้ยังเป็นเซิร์ฟเวอร์ HTTP ข้อดีของสิ่งนี้คือคุณไม่จำเป็นต้องใช้โปรโตคอลใหม่ที่อาจเป็นไปได้ว่ามีข้อผิดพลาดและอาจไม่ได้ทดสอบและคุณสามารถดีบักแอปของคุณได้โดยตรงโดยใช้เว็บเบราว์เซอร์ (หรือโดยทั่วไปcurl) และคุณไม่จำเป็นต้องมีเว็บเซิร์ฟเวอร์ที่ได้รับการแก้ไขเพื่อรองรับแอปของคุณมีเพียงเว็บเซิร์ฟเวอร์ใด ๆ ที่สามารถทำ reverse proxying หรือ redirects ได้

ทำไมต้องใช้ Apache / Nginx

เมื่อคุณให้บริการแอป node.js โปรดทราบว่าคุณเป็นผู้สร้างเว็บเซิร์ฟเวอร์ของคุณเอง ข้อบกพร่องที่อาจเกิดขึ้นในแอปของคุณเป็นข้อบกพร่องที่ใช้ประโยชน์ได้โดยตรงบนอินเทอร์เน็ต บางคน (แก้ตัว) ไม่สบายใจกับเรื่องนี้

การเพิ่มเลเยอร์ของ Apache หรือ Nginx ที่ด้านหน้าแอป node.js หมายความว่าคุณมีซอฟต์แวร์ที่ผ่านการทดสอบการต่อสู้และผ่านการทดสอบความปลอดภัยบนอินเทอร์เน็ตที่ใช้งานจริงเป็นอินเทอร์เฟซสำหรับแอปของคุณ มันเพิ่มเวลาแฝงเล็กน้อย (reverse proxying) แต่ส่วนใหญ่คิดว่ามันคุ้มค่า

สิ่งนี้เคยเป็นคำแนะนำมาตรฐานในช่วงแรก ๆ ของ node.js แต่ทุกวันนี้ยังมีเว็บไซต์และบริการบนเว็บที่เปิดเผย node.js โดยตรงกับอินเทอร์เน็ต http.Serverโมดูลคือตอนนี้ค่อนข้างดีการต่อสู้ผ่านการทดสอบบนอินเทอร์เน็ตที่จะเชื่อถือได้


1
ฉันได้อ่านในเธรด SO ที่คล้ายกันว่าการวางเลเยอร์ Nginx หรือ Apache ไว้ด้านหน้า Node "จะนำธรรมชาติที่ไม่ปิดกั้น" ไป มีความคิดเห็นเกี่ยวกับเรื่องนี้ไหม
MrfksIV

4
@MrfksIV ทั้ง Nginx และ Apache2 ไม่ปิดกั้น ในความเป็นจริงพวกเขาใช้งาน nonblocking มานานก่อนที่ node.js จะมีอยู่ อย่าใช้ Apache1
slebetman

14

NodeJs สร้างเซิร์ฟเวอร์ของตัวเอง อย่างที่คุณเห็นคำศัพท์ค่อนข้างชัดเจน:

http.createServer(app).listen(3000);

สร้างเซิร์ฟเวอร์และรับฟังคำขอ http บนพอร์ต 3000

เราใช้ nginx ในหนึ่งในโปรเจ็กต์ของเรา แต่มันเหมือนกับตัวโหลดบาลานซ์สำหรับอินสแตนซ์ nodejs หลายตัว

สมมติว่าคุณมีอินสแตนซ์ nodejs สองรายการที่ทำงานบนพอร์ต 3000 และ 3001 ตอนนี้คุณยังสามารถใช้nginxเป็นเซิร์ฟเวอร์เพื่อรับฟังการhttpโทรจริงของคุณได้port 80และอาจต้องการเปลี่ยนเส้นทางคำขอของคุณไปยังnodejsเซิร์ฟเวอร์หรือเซิร์ฟเวอร์อื่น ๆ เช่นไฟล์loadbalancer. ดังนั้นคุณยังสามารถใช้สิ่งที่ให้กับnginxnodejs

คำถามที่ดีอยู่แล้วถามว่าที่นี่


1
จริงๆแล้วฉันไม่ได้ให้ความสำคัญกับ nginx มากเกินไป ฉันสงสัยเกี่ยวกับความแตกต่างระหว่าง "เซิร์ฟเวอร์" node.js กับ "เซิร์ฟเวอร์" อื่น ๆ เช่น apache หรือ nginx ฉันไม่เข้าใจว่าสิ่งที่บรรจุอยู่ (เช่นรหัสโหนด) สามารถเทียบเคียงกับคอนเทนเนอร์ได้อย่างไร (เช่น apache) ... แต่ฉันเดาว่าความเข้าใจนี้ไม่ถูกต้อง ตอนนี้ฉันรู้แล้วว่ารหัส node.js ฟังพอร์ต 3000 เหมือนกับที่ Apache ฟังพอร์ต 80 .... ดังนั้นฉันเดาว่ามันคล้ายกัน ดังนั้นจึงเป็นเรื่องจริงที่จะบอกว่าเซิร์ฟเวอร์ทั้งสองมีจุดแข็งและจุดอ่อนของตัวเอง?
ขอบคุณ

2
createServer เพิ่งสร้างพอร์ตการฟัง มันไม่ได้ทำหน้าที่อะไรเลย
Roger

1
อะไรคือจุดประสงค์ของการมี nodejs ใช้ createServer เพื่อฟังบนพอร์ตถ้ามันจะไม่ให้บริการบางอย่างตามคำขอไปยังพอร์ตนั้น ... ดังนั้นจึงไม่ทางใดก็ทางหนึ่งโดยการขยายตรรกะ "เซิร์ฟเวอร์" ไม่ใช่หรือ?
GG2

@ RogerF.Gay ... มันสร้างฟังบนพอร์ตที่ระบุและเรียกใช้ฟังก์ชันการโทรกลับตามคำขอที่ไม่ได้รับ นั่นคือสิ่งที่ฉันจะบอกว่ามันสร้างเซิร์ฟเวอร์
Naeem Shaikh

1
@Naeem Shaikh มันไม่ได้ให้บริการอะไรเลย การเรียกสิ่งที่ไม่ให้บริการเซิร์ฟเวอร์ไม่สมเหตุสมผล
Roger

1

สมมติมีโรงแรมชื่อ Apache Hotel ซึ่งมีบริกรสำหรับลูกค้าแต่ละคน

ทันทีที่ลูกค้าสั่งสลัดพนักงานเสิร์ฟก็ไปหาพ่อครัวและบอกเขา ในขณะที่พ่อครัวกำลังเตรียมอาหารบริกรก็รอ ที่นี่

Chef => File System,

Waiter => Thread,

Customer => Event.

แม้ว่าลูกค้าจะสั่งน้ำเปล่าพนักงานเสิร์ฟก็นำมาเสิร์ฟหลังจากเสิร์ฟสลัดเท่านั้น บริกรรอต่อไปจนกว่าจะปรุงสลัดโดยเชฟ สถานะนี้เรียกว่าสถานะการปิดกั้น แม้ว่าโรงแรมจะเติบโตขึ้นลูกค้าแต่ละรายก็ควรมีพนักงานเสิร์ฟที่แตกต่างกันเพื่อให้บริการ สิ่งนี้จะเพิ่มการบล็อกเธรด (พนักงานเสิร์ฟ)

ตอนนี้มาที่ Node Hotel มีบริกรเพียงคนเดียวสำหรับลูกค้าทั้งหมด หากลูกค้าคนแรกสั่งซุปพนักงานเสิร์ฟจะบอกพ่อครัวและไปหาลูกค้าคนที่สอง หลังจากอาหารพร้อมบริกรส่งให้ลูกค้า ที่นี่ลูกค้าจะไม่รอ สถานะนี้เรียกว่าสถานะไม่ปิดกั้น บริกรเดียว (เธรด) เซิร์ฟเวอร์ทั้งหมดของลูกค้าและทำให้พวกเขามีความสุข

ดังนั้นโหนดซึ่งเป็นแอปพลิเคชั่นเธรดเดียวจึงเร็วมาก

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.