Node.js คืออะไร? อธิบายรันไทม์ JavaScript

ความสามารถในการปรับขยายเวลาในการตอบสนองและปริมาณงานเป็นตัวบ่งชี้ประสิทธิภาพหลักสำหรับเว็บเซิร์ฟเวอร์ การรักษาเวลาในการตอบสนองให้ต่ำและปริมาณงานสูงในขณะที่การปรับขนาดขึ้นและลงไม่ใช่เรื่องง่าย Node.js เป็นสภาพแวดล้อมรันไทม์ของ JavaScript ที่มีเวลาแฝงต่ำและปริมาณงานสูงโดยใช้วิธีการ "ไม่บล็อก" ในการให้บริการคำขอ กล่าวอีกนัยหนึ่ง Node.js ไม่เสียเวลาหรือทรัพยากรในการรอการร้องขอ I / O เพื่อส่งคืน

ในแนวทางดั้งเดิมในการสร้างเว็บเซิร์ฟเวอร์สำหรับการร้องขอหรือการเชื่อมต่อที่เข้ามาแต่ละครั้งเซิร์ฟเวอร์จะสร้างเธรดการดำเนินการใหม่หรือแม้แต่แยกกระบวนการใหม่เพื่อจัดการคำขอและส่งการตอบกลับ ตามแนวคิดแล้วสิ่งนี้เหมาะสมอย่างยิ่ง แต่ในทางปฏิบัติจะมีค่าใช้จ่ายจำนวนมาก

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

Node.js ใช้แนวทางอื่น มันวิ่งห่วงเหตุการณ์เดียวเธรดลงทะเบียนกับระบบที่จะเชื่อมต่อการจัดการและการเชื่อมต่อแต่ละใหม่ทำให้เกิด JavaScript ฟังก์ชันการเรียกกลับไปในกองไฟ ฟังก์ชันเรียกกลับสามารถจัดการกับคำร้องขอที่มีการเรียก I / O ที่ไม่ปิดกั้นและหากจำเป็นสามารถสร้างเธรดจากพูลเพื่อดำเนินการบล็อกหรือการดำเนินการที่ใช้ CPU มากและเพื่อโหลดบาลานซ์ระหว่างแกน CPU วิธีการของ Node ในการปรับขนาดด้วยฟังก์ชันการเรียกกลับต้องใช้หน่วยความจำน้อยกว่าในการจัดการการเชื่อมต่อมากกว่าสถาปัตยกรรมที่แข่งขันกันส่วนใหญ่ที่ปรับขนาดด้วยเธรดรวมถึง Apache HTTP Server เซิร์ฟเวอร์แอ็พพลิเคชัน Java ต่างๆ IIS และ ASP.NET และ Ruby on Rails

Node.js มีประโยชน์มากสำหรับแอปพลิเคชันเดสก์ท็อปนอกเหนือจากเซิร์ฟเวอร์ โปรดทราบว่าแอปพลิเคชัน Node ไม่ได้ จำกัด อยู่ที่ JavaScript แท้ คุณสามารถใช้ภาษาใดก็ได้ที่เปลี่ยนเป็น JavaScript เช่น TypeScript และ CoffeeScript Node.js ประกอบด้วยเอ็นจิ้น Google Chrome V8 JavaScript ซึ่งรองรับไวยากรณ์ ECMAScript 2015 (ES6) โดยไม่จำเป็นต้องใช้ตัวส่งสัญญาณ ES6 ถึง ES5 เช่น Babel

ยูทิลิตี้ Node ส่วนใหญ่มาจากไลบรารีแพ็คเกจขนาดใหญ่ซึ่งสามารถเข้าถึงได้จากnpmคำสั่ง NPM ซึ่งเป็น Node package manager เป็นส่วนหนึ่งของการติดตั้ง Node.js มาตรฐานแม้ว่าจะมีเว็บไซต์ของตัวเองก็ตาม

ประวัติ JavaScript บางส่วน

ในปี 1995 Brendan Eich ซึ่งเป็นผู้รับเหมาของ Netscape ได้สร้างภาษา JavaScript เพื่อใช้งานในเว็บเบราว์เซอร์ภายใน 10 วันเมื่อเรื่องราวดำเนินไป เริ่มแรก JavaScript มีวัตถุประสงค์เพื่อเปิดใช้งานภาพเคลื่อนไหวและการปรับแต่งอื่น ๆ ของรูปแบบวัตถุเอกสารเบราว์เซอร์ (DOM) มีการเปิดตัวเวอร์ชันของ JavaScript สำหรับ Netscape Enterprise Server หลังจากนั้นไม่นาน

ชื่อ JavaScript ถูกเลือกเพื่อวัตถุประสงค์ทางการตลาดเนื่องจากภาษา Java ของ Sun ได้รับความนิยมอย่างกว้างขวางในเวลานั้น ในความเป็นจริงภาษา JavaScript นั้นมีพื้นฐานมาจากภาษา Scheme และ Self เป็นหลักโดยมีความหมายเพียงผิวเผินเหมือน Java

ในขั้นต้นโปรแกรมเมอร์หลายคนไม่สนใจ JavaScript ว่าไม่มีประโยชน์สำหรับ "งานจริง" เนื่องจากล่ามทำงานตามลำดับความสำคัญช้ากว่าภาษาที่คอมไพล์ สิ่งนี้เปลี่ยนไปเมื่อความพยายามในการวิจัยหลายอย่างที่มุ่งทำให้ JavaScript เร็วขึ้นเริ่มเกิดผล ที่โดดเด่นที่สุดคือเอ็นจิ้น Google Chrome V8 JavaScript แบบโอเพนซอร์สซึ่งทำการคอมไพล์อินไลน์และการเพิ่มประสิทธิภาพโค้ดแบบไดนามิกแบบทันเวลาสามารถทำงานได้ดีกว่าโค้ด C ++ สำหรับบางโหลดและมีประสิทธิภาพเหนือกว่า Python สำหรับกรณีการใช้งานส่วนใหญ่

แพลตฟอร์ม Node.js ที่ใช้ JavaScript เปิดตัวในปี 2009 โดย Ryan Dahl สำหรับ Linux และ MacOS เป็นทางเลือกที่ปรับขนาดได้มากกว่าสำหรับเซิร์ฟเวอร์ Apache HTTP NPM เขียนโดย Isaac Schlueter เปิดตัวในปี 2010 Node.js เวอร์ชันดั้งเดิมของ Windows เปิดตัวในปี 2554

Joyent เป็นเจ้าของควบคุมและสนับสนุนความพยายามในการพัฒนา Node.js เป็นเวลาหลายปี ในปี 2558 โครงการ Node.js ได้ถูกส่งต่อไปยังมูลนิธิ Node.js และอยู่ภายใต้การควบคุมของคณะกรรมการอำนวยการด้านเทคนิคของมูลนิธิ Node.js ยังได้รับการยอมรับให้เป็นโครงการความร่วมมือของ Linux Foundation ในปี 2019 Node.js Foundation และ JS Foundation ได้รวมตัวกันเพื่อก่อตั้ง OpenJS Foundation

สถาปัตยกรรม Node.js พื้นฐาน

ในระดับสูง Node.js จะรวมเอ็นจิ้น Google V8 JavaScript, ลูปเหตุการณ์ที่ไม่ปิดกั้นเธรดเดียวและ I / O API ระดับต่ำ โค้ดตัวอย่างแบบถอดลงที่แสดงด้านล่างแสดงรูปแบบเซิร์ฟเวอร์ HTTP พื้นฐานโดยใช้ฟังก์ชันลูกศร ES6 (ฟังก์ชัน Lambda ที่ไม่ระบุชื่อที่ประกาศโดยใช้โอเปอเรเตอร์ลูกศรอ้วน=>) สำหรับการเรียกกลับ

จุดเริ่มต้นของโค้ดจะโหลดโมดูล HTTP ตั้งค่าhostnameตัวแปรเซิร์ฟเวอร์เป็นlocalhost(127.0.0.1) และตั้งค่าportตัวแปรเป็น 3000 จากนั้นจะสร้างเซิร์ฟเวอร์และฟังก์ชันเรียกกลับในกรณีนี้คือฟังก์ชันลูกศรอ้วนที่ส่งคืนค่าเดียวกันเสมอ ตอบสนองต่อการร้องขอใด ๆ : statusCode200 (ความสำเร็จ), ”Hello World\n”พิมพ์ข้อความธรรมดาเนื้อหาและการตอบสนองของข้อความสุดท้ายมันบอกให้เซิร์ฟเวอร์ฟังบนlocalhostพอร์ต 3000 (ผ่านซ็อกเก็ต) และกำหนดการเรียกกลับเพื่อพิมพ์ข้อความบันทึกบนคอนโซลเมื่อเซิร์ฟเวอร์เริ่มรับฟัง หากคุณเรียกใช้รหัสนี้ในเทอร์มินัลหรือคอนโซลโดยใช้nodeคำสั่งแล้วเรียกดู localhost: 3000 โดยใช้เว็บเบราว์เซอร์ใดก็ได้บนเครื่องเดียวกันคุณจะเห็น“ Hello World” ในเบราว์เซอร์ของคุณ หากต้องการหยุดเซิร์ฟเวอร์ให้กด Control-C ในหน้าต่างเทอร์มินัล

โปรดทราบว่าการโทรทุกครั้งในตัวอย่างนี้เป็นแบบอะซิงโครนัสและไม่ปิดกั้น เรียกใช้ฟังก์ชันการเรียกกลับเพื่อตอบสนองต่อเหตุการณ์ การcreateServerเรียกกลับจะจัดการกับเหตุการณ์คำขอของไคลเอ็นต์และส่งกลับการตอบกลับ การlistenเรียกกลับจะจัดการlisteningเหตุการณ์

ไลบรารี Node.js

ดังที่คุณเห็นทางด้านซ้ายของรูปด้านล่าง Node.js มีฟังก์ชันการทำงานมากมายในไลบรารี โมดูล HTTP ที่เราใช้ในโค้ดตัวอย่างก่อนหน้านี้มีทั้งคลาสไคลเอนต์และเซิร์ฟเวอร์ดังที่คุณเห็นทางด้านขวาของรูป ฟังก์ชันเซิร์ฟเวอร์ HTTPS โดยใช้ TLS หรือ SSL อยู่ในโมดูลแยกต่างหาก

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

คุณสามารถแก้ไขได้แม้ว่าจะต้องใช้การเขียนโปรแกรมเพิ่มเติม ในการเริ่มต้น Node.js สามารถวางไข่กระบวนการย่อยและดูแลท่อระหว่างพาเรนต์และชายด์ได้เช่นเดียวกับวิธีที่ระบบpopen(3)เรียกใช้child_process.spawn() และวิธีการที่เกี่ยวข้อง

โมดูลคลัสเตอร์น่าสนใจยิ่งกว่าโมดูลกระบวนการลูกสำหรับการสร้างเซิร์ฟเวอร์ที่ปรับขนาดได้ cluster.fork()กระบวนการวิธี spawns คนงานที่ใช้พอร์ตเซิร์ฟเวอร์ของผู้ปกครองโดยใช้child_process.spawn()ที่อยู่ใต้ผ้าห่ม คลัสเตอร์หลักจะกระจายการเชื่อมต่อขาเข้าระหว่างผู้ปฏิบัติงานโดยใช้อัลกอริทึมแบบ round-robin ที่ไวต่อการโหลดกระบวนการของผู้ปฏิบัติงานโดยค่าเริ่มต้น

โปรดทราบว่า Node.js ไม่มีตรรกะการกำหนดเส้นทาง หากคุณต้องการรักษาสถานะของการเชื่อมต่อในคลัสเตอร์คุณจะต้องเก็บเซสชันและอ็อบเจ็กต์การเข้าสู่ระบบไว้ที่อื่นนอกเหนือจาก RAM ของผู้ปฏิบัติงาน

ระบบนิเวศของแพ็คเกจ Node.js

การลงทะเบียน NPM โฮสต์โค้ด Node.js ฟรีและใช้ซ้ำได้มากกว่า 1.2 ล้านชุดซึ่งทำให้เป็นรีจิสทรีซอฟต์แวร์ที่ใหญ่ที่สุดในโลก โปรดสังเกตว่าแพ็กเกจ NPM ส่วนใหญ่(โดยพื้นฐานแล้วคือโฟลเดอร์หรือรายการรีจิสตรี NPM ที่มีโปรแกรมที่อธิบายโดยไฟล์ package.json) มีโมดูลหลายโมดูล (โปรแกรมที่คุณโหลดด้วยrequireคำสั่ง) มันง่ายที่จะสับสนทั้งสองคำ แต่ในบริบทนี้มีความหมายเฉพาะและไม่ควรเปลี่ยนกัน

NPM สามารถจัดการแพ็กเกจที่อ้างอิงภายในของโปรเจ็กต์เฉพาะเช่นเดียวกับเครื่องมือ JavaScript ที่ติดตั้งทั่วโลก เมื่อใช้เป็นตัวจัดการการพึ่งพาสำหรับโปรเจ็กต์ภายใน NPM สามารถติดตั้งในคำสั่งเดียวการอ้างอิงทั้งหมดของโปรเจ็กต์ผ่านไฟล์ package.json เมื่อใช้สำหรับการติดตั้งส่วนกลาง NPM มักต้องการสิทธิ์ของระบบ (sudo)

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

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

ตัวอย่างเช่นเฟรมเวิร์ก Express ซึ่งเป็นเฟรมเวิร์กแอปพลิเคชันบนเว็บ Node.js ที่เรียบง่ายและยืดหยุ่นมีชุดคุณลักษณะที่มีประสิทธิภาพสำหรับการสร้างเว็บแอปพลิเคชันแบบหน้าเดียวและหลายหน้าและแบบไฮบริด แม้ว่าที่เก็บ Expresscode ที่สามารถโคลนได้อย่างง่ายดายจะอยู่ที่ //github.com/expressjs/express และเอกสาร Express อยู่ที่ //expressjs.com/ วิธีที่รวดเร็วในการเริ่มต้นใช้ Express คือการติดตั้งลงในการพัฒนาการทำงานในพื้นที่ที่เริ่มต้นแล้ว ไดเร็กทอรีด้วยnpmคำสั่งตัวอย่างเช่น:

$ npm ติดตั้งด่วน - บันทึก

—saveตัวเลือกที่เป็นจริงตามค่าเริ่มต้นใน NPM 5.0 และต่อมาบอกผู้จัดการแพคเกจเพื่อเพิ่มโมดูล Express เพื่อรายการการอ้างอิงในแฟ้ม package.json หลังจากการติดตั้ง

อีกวิธีที่รวดเร็วในการเริ่มใช้ Express คือการติดตั้งเครื่องกำเนิดไฟฟ้าที่เรียกexpress(1) ใช้งานได้ทั่วโลกจากนั้นใช้เพื่อสร้างแอปพลิเคชันในเครื่องในโฟลเดอร์ที่ทำงานใหม่:

$ npm ติดตั้ง -g express-generator @ 4

$ express / tmp / foo && cd / tmp / foo

เมื่อสำเร็จแล้วคุณสามารถใช้ NPM เพื่อติดตั้งการอ้างอิงที่จำเป็นทั้งหมดและเริ่มต้นเซิร์ฟเวอร์ตามเนื้อหาของไฟล์ package.json ที่สร้างโดยเครื่องกำเนิดไฟฟ้า:

$ npm ติดตั้ง

เริ่มต้น $ npm

เป็นการยากที่จะเลือกไฮไลต์จากแพ็คเกจกว่าล้านรายการใน NPM แต่มีบางหมวดหมู่ที่โดดเด่น Express เป็นตัวอย่างที่เก่าแก่ที่สุดและโดดเด่นที่สุดของกรอบงาน Node.js อีกประเภทใหญ่ในที่เก็บ NPM คือยูทิลิตีการพัฒนา JavaScript รวมถึง browserify โมดูลบันเดิล bower ตัวจัดการแพ็คเกจเบราว์เซอร์ ฮึดฮัดตัววิ่งงาน JavaScript; และอึกระบบสร้างสตรีมมิ่ง สุดท้ายหมวดหมู่ที่สำคัญสำหรับนักพัฒนา Node.js ขององค์กรคือไคลเอนต์ฐานข้อมูลซึ่งมีมากกว่า 8,000 รายการรวมถึงโมดูลยอดนิยมเช่น redis, พังพอน, firebase และ pg, ไคลเอนต์ PostgreSQL

สรุปได้ว่า Node.js คือสภาพแวดล้อมรันไทม์ JavaScript ข้ามแพลตฟอร์มสำหรับเซิร์ฟเวอร์และแอปพลิเคชัน สร้างขึ้นจากลูปเหตุการณ์แบบเธรดเดียวที่ไม่ปิดกั้นเอ็นจิ้น Google Chrome V8 JavaScript และ I / O API ระดับต่ำ เทคนิคต่างๆรวมถึงโมดูลคลัสเตอร์ทำให้แอป Node.js สามารถปรับขนาดได้เกินแกน CPU เดียว นอกเหนือจากฟังก์ชันการทำงานหลักแล้ว Node.js ได้สร้างแรงบันดาลใจให้กับระบบนิเวศของแพ็กเกจมากกว่าหนึ่งล้านแพ็กเกจที่ลงทะเบียนและกำหนดเวอร์ชันในที่เก็บ NPM และสามารถติดตั้งโดยใช้บรรทัดคำสั่ง NPM หรือทางเลือกอื่นเช่น Yarn