ข้อใดจะดีกว่าสำหรับงานพร้อมกันบน node.js เส้นใย? คนทำงานเว็บ? หรือเธรด?


111

ฉันสะดุดกับ node.js เมื่อหลายปีก่อนและชอบมันมาก แต่ในไม่ช้าฉันก็พบว่ามันขาดความสามารถในการทำงานที่ต้องใช้ CPU มาก ดังนั้นฉันจึงเริ่ม googling และได้รับคำตอบเหล่านี้เพื่อแก้ปัญหา: Fibers, Webworkers และ Threads (thread-a-gogo) ตอนนี้จะใช้อันไหนเป็นความสับสนและหนึ่งในนั้นจำเป็นต้องใช้อย่างแน่นอน - จุดประสงค์ของการมีเซิร์ฟเวอร์ที่ IO ดีแค่ไหนและไม่มีอย่างอื่น? คำแนะนำที่จำเป็น!

อัพเดท:

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

นั่นคือสิ่งที่ฉันคิด ความคิดนี้ดีหรือไม่? ฉันยังใหม่กับกระบวนการและเธรดทั้งหมดนี้ดังนั้นจึงไม่มีความเชี่ยวชาญใด ๆ กรุณาแบ่งปันความคิดเห็นของคุณ

ขอบคุณ. :)


โปรดทราบ: Workers เป็นคุณสมบัติของเบราว์เซอร์ - ไม่ใช่คุณสมบัติ Javascript
FredTheWebGuy

ฉันเห็นว่า คำถามของฉันเกี่ยวกับ node.js - รหัสเซิร์ฟเวอร์ไม่ใช่เกี่ยวกับฝั่งไคลเอ็นต์!
Parth Thakkar

เพียงแค่ชี้แจง - ฉันเห็นว่าคำถามเดิมเกี่ยวกับ Webworkers ใน NodeJs ซึ่งเป็นไปไม่ได้ - NodeJs ใช้ "เธรด" อย่างไรก็ตามมีโมดูล NodeJS ลอยอยู่รอบ ๆ ซึ่งอนุญาตให้ใช้ไวยากรณ์ WebWorker ภายในรันไทม์ NodeJs
FredTheWebGuy

คำตอบ:


331

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

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

- เฮ้ฮาซันฉันคิดว่าคุณเป็นมือใหม่หรือวัยเรียนตั้งแต่สมัยปู่ของฉัน !!! ทำไมคุณไม่สร้างเธรดและทำให้เร็วขึ้น?

- โอ้เรามีแกน CPU เพียงตัวเดียว

- แล้วไง? สร้างเธรดแมนทำให้เร็วขึ้น!

- มันไม่ได้ผลเช่นนั้น ถ้าฉันสร้างเธรดฉันจะทำให้ช้าลง เนื่องจากฉันจะเพิ่มค่าใช้จ่ายจำนวนมากให้กับระบบเพื่อสลับไปมาระหว่างเธรดพยายามให้เวลากับพวกเขาในระยะเวลาอันสั้นและในกระบวนการของฉันพยายามสื่อสารระหว่างเธรดเหล่านี้ นอกจากข้อเท็จจริงทั้งหมดนี้แล้วฉันยังต้องคิดด้วยว่าฉันจะแบ่งงานเดียวออกเป็นหลาย ๆ ชิ้นที่สามารถทำควบคู่กันได้อย่างไร

- โอเคโอเคฉันเห็นว่าคุณน่าสงสาร มาใช้คอมพิวเตอร์กันเถอะมันมี 32 คอร์!

- ว้าวคุณสุดยอดเพื่อนรักของฉันขอบคุณมาก ฉันรู้สึกทราบซึ้ง!

จากนั้นเรากลับไปทำงาน ตอนนี้เรามี 32 คอร์ cpu ขอบคุณเพื่อนที่ร่ำรวยของเรา กฎที่เราต้องปฏิบัติเพิ่งมีการเปลี่ยนแปลง ตอนนี้เราต้องการใช้ความมั่งคั่งทั้งหมดที่เราได้รับ

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

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

- เฮซันคุณยังทำงานแบบเธรดเดี่ยวอยู่หรือเปล่า? เกิดอะไรขึ้นกับคุณผู้ชาย? ฉันให้สิ่งที่คุณต้องการ คุณไม่มีข้อแก้ตัวอีกต่อไป สร้างเธรดทำให้ทำงานได้เร็วขึ้น

- ฉันได้แบ่งงานออกเป็นชิ้น ๆ และทุกกระบวนการจะทำงานกับหนึ่งในชิ้นส่วนเหล่านี้ควบคู่กันไป

- ทำไมคุณไม่สร้างเธรด?

- ขออภัยฉันคิดว่ามันใช้งานไม่ได้ คุณสามารถใช้คอมพิวเตอร์ของคุณถ้าคุณต้องการ?

- ไม่เป็นไรฉันใจเย็นฉันไม่เข้าใจว่าทำไมคุณไม่ใช้เธรด?

- ขอบคุณสำหรับคอมพิวเตอร์ :) ฉันแบ่งงานออกเป็นชิ้น ๆ แล้วและฉันสร้างกระบวนการเพื่อทำงานกับชิ้นส่วนเหล่านี้ควบคู่กันไป แกนซีพียูทั้งหมดจะถูกใช้อย่างเต็มที่ ฉันสามารถทำได้ด้วยเธรดแทนที่จะเป็นกระบวนการ แต่โหนดมีวิธีนี้และ Parth Thakkar เจ้านายของฉันต้องการให้ฉันใช้ Node

- โอเคแจ้งให้เราทราบหากคุณต้องการคอมพิวเตอร์เครื่องอื่น : p

ถ้าฉันสร้าง 33 กระบวนการแทนที่จะเป็น 32 ตัวกำหนดตารางเวลาของระบบปฏิบัติการจะหยุดเธรดชั่วคราวเริ่มต้นอีกอันหยุดชั่วคราวหลังจากผ่านไปสักระยะเริ่มกระบวนการอื่นอีกครั้ง ... นี่เป็นค่าใช้จ่ายที่ไม่จำเป็น ฉันไม่ต้องการมัน. ในระบบที่มี 32 คอร์ผมไม่อยากสร้าง 32 โปรเซสเลยด้วยซ้ำ31 ก็ทำได้ดีกว่า เพราะไม่ใช่แค่แอปพลิเคชันของฉันเท่านั้นที่จะทำงานบนระบบนี้ การปล่อยให้มีห้องเล็ก ๆ น้อย ๆ สำหรับสิ่งอื่น ๆ อาจเป็นเรื่องดีโดยเฉพาะอย่างยิ่งถ้าเรามี 32 ห้อง

ผมเชื่อว่าเราอยู่บนหน้าเดียวกันในขณะนี้เกี่ยวกับการใช้หน่วยประมวลผลอย่างเต็มที่สำหรับงาน CPU สูง

- อืมฮะซันฉันขอโทษที่ล้อเลียนคุณนิดหน่อย ฉันเชื่อว่าฉันเข้าใจคุณดีขึ้นแล้ว แต่ยังมีบางอย่างที่ฉันต้องการคำอธิบาย: อะไรคือเรื่องปากต่อปากเกี่ยวกับการรันเธรดนับร้อย ฉันอ่านทุกที่ที่เธรดสร้างได้เร็วและโง่กว่ากระบวนการฟอร์ก? คุณแยกกระบวนการแทนที่จะเป็นเธรดและคุณคิดว่ามันสูงที่สุดที่คุณจะได้รับจาก Node แล้ว Node ไม่เหมาะสมกับงานลักษณะนี้หรือไม่?

- ไม่ต้องกังวลฉันก็เท่เหมือนกัน ทุกคนพูดสิ่งเหล่านี้ดังนั้นฉันคิดว่าฉันเคยได้ยินพวกเขา

- งั้นเหรอ? โหนดไม่ดีสำหรับสิ่งนี้?

- โหนดเหมาะอย่างยิ่งสำหรับสิ่งนี้แม้ว่าเธรดจะดีเช่นกัน สำหรับค่าใช้จ่ายในการสร้างเธรด / กระบวนการ ในสิ่งที่คุณทำซ้ำบ่อย ๆ ทุกๆมิลลิวินาทีมีค่า อย่างไรก็ตามฉันสร้างเพียง 32 โปรเซสและใช้เวลาเล็กน้อย มันจะเกิดขึ้นเพียงครั้งเดียว มันจะไม่สร้างความแตกต่างใด ๆ

- ฉันต้องการสร้างเธรดหลายพันเธรดเมื่อใด

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

- โหนดแตกต่างกันอย่างไร ขวา?

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

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

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

- แล้วโปรเซสจะจัดการ 2 คำขอพร้อมกันได้อย่างไร?

- กระบวนการสามารถรองรับคำขอได้หลายหมื่นรายการในแต่ละครั้งตราบเท่าที่ระบบของเรามีทรัพยากรเพียงพอ (RAM, เครือข่าย ฯลฯ ) การทำงานของฟังก์ชันเหล่านั้นคือความแตกต่างที่สำคัญ

- อืมตอนนี้ฉันควรจะตื่นเต้นไหม?

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

- ฟังดูซับซ้อนเกินไป?

- ไม่ไม่ฉันอาจฟังดูซับซ้อน แต่ระบบนั้นง่ายมากและมันก็สมเหตุสมผลดี

ตอนนี้ฉันต้องการหยุดการอ้างถึงบทสนทนาระหว่างนักพัฒนาสองคนนี้และจบคำตอบของฉันหลังจากดูตัวอย่างสั้น ๆ ครั้งสุดท้ายว่าฟังก์ชันเหล่านี้ทำงานอย่างไร

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

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

วิธีซิงโครนัส:

Open File
Repeat This:    
    Read Some
    Do the work

วิธีอะซิงโครนัส:

Open File and Do this when it is ready: // Our function returns
    Repeat this:
        Read Some and when it is ready: // Returns again
            Do some work

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

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


(1) เว้นแต่คุณจะสร้างไลบรารีในภาษาอื่นเช่น C / C ++ ซึ่งในกรณีนี้คุณยังไม่สร้างเธรดสำหรับแบ่งงาน สำหรับงานประเภทนี้คุณมีเธรดสองเธรดซึ่งหนึ่งในนั้นจะสื่อสารกับโหนดต่อไปในขณะที่อีกเธรดทำงานจริง

(2) ในความเป็นจริงทุกกระบวนการ Node มีหลายเธรดด้วยเหตุผลเดียวกับที่ฉันกล่าวไว้ในเชิงอรรถแรก อย่างไรก็ตามนี่ไม่ใช่วิธีที่เหมือนกับ 1,000 เธรดที่ทำงานคล้ายกัน เธรดพิเศษเหล่านี้มีไว้สำหรับสิ่งต่างๆเช่นการยอมรับเหตุการณ์ IO และเพื่อจัดการการส่งข้อความระหว่างกระบวนการ

อัปเดต (ตอบคำถามที่ดีในความคิดเห็น)

@ มาร์คขอบคุณสำหรับคำวิจารณ์ที่สร้างสรรค์ ในกระบวนทัศน์ของ Node คุณไม่ควรมีฟังก์ชันที่ใช้เวลาในการประมวลผลนานเกินไปเว้นแต่การเรียกอื่น ๆ ทั้งหมดในคิวได้รับการออกแบบให้ทำงานทีละรายการ ในกรณีของงานที่มีราคาแพงในการคำนวณหากเราดูภาพโดยละเอียดแล้วเราจะเห็นว่านี่ไม่ใช่คำถามที่ว่า "เราควรใช้เธรดหรือกระบวนการหรือไม่" แต่มีคำถามว่า "เราจะแบ่งงานเหล่านี้อย่างสมดุลออกเป็นงานย่อยที่เราสามารถรันควบคู่กันได้อย่างไรโดยใช้แกน CPU หลายตัวในระบบ" สมมติว่าเราจะประมวลผลไฟล์วิดีโอ 400 ไฟล์ในระบบที่มี 8 คอร์ หากเราต้องการประมวลผลทีละไฟล์เราจำเป็นต้องมีระบบที่จะประมวลผลส่วนต่างๆของไฟล์เดียวกันซึ่งในกรณีนี้ระบบมัลติเธรดเดี่ยวอาจสร้างได้ง่ายกว่าและมีประสิทธิภาพมากยิ่งขึ้น เรายังคงสามารถใช้ Node สำหรับสิ่งนี้ได้โดยการรันหลายกระบวนการและส่งผ่านข้อความระหว่างกันเมื่อจำเป็นต้องใช้สถานะการแบ่งปัน / การสื่อสาร ดังที่ฉันได้กล่าวไปแล้ววิธีการแบบหลายกระบวนการกับโหนดคือเช่นเดียวกับวิธีการแบบมัลติเธรดในงานประเภทนี้ แต่ไม่มากไปกว่านั้น อีกครั้งอย่างที่ฉันบอกไปก่อนหน้านี้สถานการณ์ที่ Node ส่องคือเมื่อเรามีงานเหล่านี้มาเป็นข้อมูลเข้าสู่ระบบจากหลายแหล่งเนื่องจากการรักษาการเชื่อมต่อจำนวนมากพร้อมกันนั้นเบากว่าใน Node มากเมื่อเทียบกับเธรดต่อการเชื่อมต่อหรือกระบวนการต่อการเชื่อมต่อ ระบบ.

สำหรับการsetTimeout(...,0)โทร; บางครั้งการหยุดพักระหว่างงานที่เสียเวลาเพื่อให้การโทรในคิวมีส่วนแบ่งการประมวลผลที่จำเป็น การแบ่งงานในรูปแบบต่างๆสามารถช่วยคุณประหยัดจากสิ่งเหล่านี้ได้ แต่ถึงกระนั้นนี่ไม่ใช่การแฮ็ก แต่เป็นเพียงวิธีการทำงานของคิวเหตุการณ์ นอกจากนี้การใช้process.nextTickเพื่อจุดมุ่งหมายนี้จะดีกว่ามากเนื่องจากเมื่อคุณใช้การsetTimeoutคำนวณและการตรวจสอบเวลาที่ผ่านไปจะเป็นสิ่งที่จำเป็นในขณะที่process.nextTickเป็นเพียงสิ่งที่เราต้องการจริงๆ: "เฮ้งานกลับไปที่จุดสิ้นสุดของคิวคุณใช้ส่วนแบ่งของคุณแล้ว! "


9
สุดทึ่ง! น่าทึ่งมาก! ฉันชอบวิธีที่คุณตอบคำถามนี้มาก! :)
Parth Thakkar

48
แน่นอน :) ฉันไม่อยากจะเชื่อเลยว่ามีคนใจร้ายมากที่นั่นลงคะแนนบทความคำตอบนี้! ผู้ถามเรียกมันว่า "Damn Amazing!" และผู้เขียนหนังสือเสนอให้ฉันเขียนบนเว็บไซต์ของเขาหลังจากเห็นสิ่งนี้ แต่อัจฉริยะบางคนก็ลงคะแนนให้ ทำไมคุณไม่แบ่งปันคุณภาพทางปัญญาที่สดใสของคุณและแสดงความคิดเห็นแทนการลงคะแนนอย่างจริงใจและแอบดูล่ะ? ทำไมสิ่งดีๆรบกวนคุณขนาดนั้น? เหตุใดคุณจึงต้องการป้องกันสิ่งที่เป็นประโยชน์ในการเข้าถึงผู้อื่นที่สามารถได้รับประโยชน์จากสิ่งนั้น
hasanyasin

9
นี่ไม่ใช่คำตอบที่ยุติธรรมอย่างสมบูรณ์ แล้วงานที่มีราคาแพงในการคำนวณที่เราไม่สามารถ "สิ้นสุด" ได้อย่างรวดเร็ว ฉันเชื่อว่าบางคนใช้การsetTimeout(...,0)แฮ็กสำหรับสิ่งนี้ แต่การใช้เธรดแยกต่างหากในสถานการณ์นี้จะดีกว่าอย่างแน่นอน?
mpen

3
@hasanyasin นี่คือคำอธิบายที่ดีที่สุดในโหนดที่ฉันพบจนถึงตอนนี้! :)
Venemo

7
@Mark โดยทั่วไปถ้ามันมีราคาแพงในการคำนวณมีตัวเลือก / โมดูลสำหรับคนงานดอกยาง / กระบวนการ ... โดยทั่วไปสำหรับสิ่งเหล่านี้ฉันใช้คิวข้อความและมีกระบวนการของผู้ปฏิบัติงานที่จัดการงานที่ a เวลาจากคิวและทำงานนั้น นอกจากนี้ยังช่วยให้สามารถปรับขนาดไปยังเซิร์ฟเวอร์หลายเครื่อง ตามบรรทัดเหล่านี้ Substack มีโมดูลจำนวนมากที่มุ่งเป้าไปที่การจัดเตรียมและการปรับขนาดที่คุณสามารถดูได้
Tracker1

34

(อัปเดต 2016: ผู้ปฏิบัติงานบนเว็บกำลังเข้าสู่io.js - Node.js fork Node.js v7 - ดูด้านล่าง)

(อัปเดต 2017: ผู้ปฏิบัติงานบนเว็บจะไม่เข้าสู่ Node.js v7 หรือ v8 - ดูด้านล่าง)

(อัปเดต 2018: ผู้ปฏิบัติงานบนเว็บกำลังเข้าสู่ Node.js Node v10.5.0 - ดูด้านล่าง)

ชี้แจงบางส่วน

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

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

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

ตามความเป็นจริงผู้ปฏิบัติงานบนเว็บเป็นแนวคิดที่เหมาะสมอย่างยิ่งสำหรับ Node ซึ่งหลายคนไม่ทราบโดยบังเอิญใช้เธรดค่อนข้างหนักและในความเป็นจริง "ทุกอย่างทำงานแบบขนานยกเว้นโค้ดของคุณ" โปรดดู:

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

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

สิ่งที่มักจะแนะนำคือให้แบ่งการดำเนินการที่ผูกกับ CPU เป็นเวลานานออกเป็นงานเล็ก ๆ (เช่นตัวอย่างในส่วน "คำตอบเดิม" ของคำตอบของฉันสำหรับ Speed ​​up setInterval ) แต่ไม่สามารถใช้งานได้จริงเสมอไปและไม่ได้ใช้มากกว่านี้ มากกว่าหนึ่งแกน CPU

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

โมดูลโหนด

มีโมดูลไม่กี่โมดูลที่ควรเพิ่ม Web Workers ไปยัง Node:

ฉันไม่ได้ใช้สิ่งเหล่านี้ แต่ฉันมีข้อสังเกตสั้น ๆ สองข้อที่อาจเกี่ยวข้อง: ณ เดือนมีนาคม 2015 node-webworker ได้รับการอัปเดตครั้งล่าสุดเมื่อ 4 ปีก่อนและ node-webworker-threads ได้รับการอัปเดตครั้งล่าสุดเมื่อเดือนที่แล้ว นอกจากนี้ฉันยังเห็นในตัวอย่างของการใช้งาน node-webworker-threads ที่คุณสามารถใช้ฟังก์ชันแทนชื่อไฟล์เป็นอาร์กิวเมนต์ของตัวสร้าง Worker ซึ่งดูเหมือนว่าอาจทำให้เกิดปัญหาเล็กน้อยหากมีการใช้งานโดยใช้เธรดที่ใช้หน่วยความจำร่วมกัน (เว้นแต่ว่า ฟังก์ชั่นใช้สำหรับเมธอด. toString () เท่านั้นและถูกคอมไพล์ในสภาพแวดล้อมที่แตกต่างกันซึ่งในกรณีนี้มันอาจจะดี - ฉันต้องมองลึกลงไปมากกว่านี้เพียงแค่แบ่งปันข้อสังเกตของฉันที่นี่)

หากมีโครงการที่เกี่ยวข้องอื่น ๆ ที่ใช้ Web Work API ใน Node โปรดแสดงความคิดเห็น

อัปเดต 1

ผมไม่ทราบว่ามันยังในขณะที่เขียน แต่บังเอิญวันหนึ่งก่อนที่ผมจะเขียนคำตอบนี้เว็บแรงงานที่ถูกเพิ่มเข้า io.js

( io.jsเป็นส่วนแยกของ Node.js - ดู: ทำไม io.js จึงตัดสินใจแยก Node.jsซึ่งเป็นการสัมภาษณ์ของ InfoWorld กับ Mikeal Rogers สำหรับข้อมูลเพิ่มเติม)

ไม่เพียง แต่พิสูจน์ประเด็นที่ว่าไม่มีสิ่งใดในผู้ปฏิบัติงานบนเว็บที่ขัดต่อหลักปรัชญาของ JavaScript โดยทั่วไปและโหนดโดยเฉพาะอย่างยิ่งเกี่ยวกับการทำงานพร้อมกัน แต่อาจส่งผลให้ผู้ปฏิบัติงานเว็บเป็นพลเมืองชั้นหนึ่งใน JavaScript ฝั่งเซิร์ฟเวอร์เช่น io js (และอาจ Node.js ในอนาคต) เช่นเดียวกับมันแล้วคือในฝั่งไคลเอ็นต์ JavaScript ในเบราว์เซอร์ที่ทันสมัย

อัปเดต 2

ในอัปเดต 1 และทวีตของฉันฉันอ้างถึงคำขอดึง io.js # 1159 ซึ่งตอนนี้เปลี่ยนเส้นทางไปยัง โหนด PR # 1159 ที่ปิดเมื่อวันที่ 8 ก.ค. และแทนที่ด้วยNode PR # 2133ซึ่งยังคงเปิดอยู่ มีการอภิปรายบางอย่างเกิดขึ้นภายใต้คำขอดึงข้อมูลเหล่านั้นซึ่งอาจให้ข้อมูลล่าสุดเกี่ยวกับสถานะของผู้ปฏิบัติงานเว็บใน io.js / Node.js

อัปเดต 3

ข้อมูลล่าสุด - ขอบคุณ NiCk Newman สำหรับการโพสต์ในความคิดเห็น: มีคนงาน: การดำเนินการครั้งแรกกระทำโดย Petka Antonov ตั้งแต่วันที่ 6 กันยายน 2015 ที่สามารถดาวน์โหลดและทดลองใช้ใน แผนภูมินี้ ดูความคิดเห็นของ NiCk Newmanสำหรับรายละเอียด

อัปเดต 4

เมื่อเดือนพฤษภาคม 2016ความคิดเห็นล่าสุดเกี่ยวกับPR # 2133 ที่ยังเปิดอยู่ - คนงาน: การใช้งานครั้งแรกมีอายุ 3 เดือน เมื่อวันที่ 30 พฤษภาคม Matheus Moreira ขอให้ฉันโพสต์อัปเดตสำหรับคำตอบนี้ในความคิดเห็นด้านล่างและเขาขอสถานะปัจจุบันของฟีเจอร์นี้ในความคิดเห็นด้านประชาสัมพันธ์

คำตอบแรกในการอภิปรายประชาสัมพันธ์ไม่น่าเชื่อ แต่ต่อมา Ben Noordhuis เขียนว่า "การรวมสิ่งนี้เป็นรูปร่างเดียวหรืออย่างอื่นอยู่ในรายการสิ่งที่ต้องทำของฉันสำหรับ v7"

ความคิดเห็นอื่น ๆ ทั้งหมดดูเหมือนจะเป็นอันดับสองและ ณ เดือนกรกฎาคม 2559 ดูเหมือนว่าWeb Workers ควรจะพร้อมใช้งานในเวอร์ชันถัดไปของ Nodeเวอร์ชัน 7.0 ที่มีแผนจะออกในเดือนตุลาคม 2559 (ไม่จำเป็นต้องอยู่ในรูปแบบของการประชาสัมพันธ์ที่แน่นอนนี้)

ขอบคุณ Matheus Moreira ที่ชี้ให้เห็นในความคิดเห็นและรื้อฟื้นการสนทนาใน GitHub

อัปเดต 5

เดือนกรกฎาคม 2016มีโมดูลบางส่วนใน npm ที่ไม่สามารถใช้งานได้มาก่อน - สำหรับรายการโมดูลที่เกี่ยวข้องทั้งหมดค้นหาnpmสำหรับผู้ปฏิบัติงานผู้ปฏิบัติงานบนเว็บ ฯลฯ หากมีสิ่งใดเป็นพิเศษหรือไม่ได้ผลสำหรับคุณโปรดโพสต์ แสดงความคิดเห็น

อัปเดต 6

ในเดือนมกราคม 2017เป็นไปได้ยากที่คนงานเว็บจะรวมเข้ากับ Node.js

คำขอดึงคนงาน # 2133 : การใช้งานครั้งแรกโดย Petka Antonov ตั้งแต่วันที่ 8 กรกฎาคม 2015 ถูกปิดในที่สุดโดย Ben Noordhuis เมื่อวันที่ 11 ธันวาคม 2016 ซึ่งแสดงความคิดเห็นว่า "การสนับสนุนแบบหลายเธรดเพิ่มโหมดความล้มเหลวใหม่มากเกินไปเพื่อประโยชน์ไม่เพียงพอ" และ "เรา ยังสามารถทำได้โดยใช้วิธีการแบบเดิม ๆ เช่นหน่วยความจำที่ใช้ร่วมกันและการทำให้เป็นอนุกรมที่มีประสิทธิภาพมากขึ้น "

สำหรับข้อมูลเพิ่มเติมโปรดดูความคิดเห็นของPR 2133บน GitHub

ขอขอบคุณ Matheus Moreira อีกครั้งที่ชี้ให้เห็นในความคิดเห็น

อัปเดต 6

ฉันยินดีที่จะแจ้งให้ทราบว่าสองสามวันที่ผ่านมาในเดือนมิถุนายน 2018 Web Worker ปรากฏใน Node v10.5.0 เป็นฟีเจอร์ทดลองที่เปิดใช้งานด้วย--experimental-workerแฟล็ก

สำหรับข้อมูลเพิ่มเติมโปรดดู:

🎉🎉🎉ในที่สุด! ฉันสามารถทำการอัปเดตครั้งที่ 7 สำหรับคำตอบ Stack Overflow อายุ 3 ปีของฉันได้โดยที่ฉันยืนยันว่าการทำเธรด a la web ไม่ได้ขัดต่อปรัชญาของ Node คราวนี้เท่านั้นที่บอกว่าเราได้มันในที่สุด! 😜👍


1
@NiCkNewman ขอบคุณ ฉันเห็นว่าคำขอดึงต้นฉบับใน io.js ถูกปิดในขณะนี้และแทนที่ด้วยคำขออื่น - ด้วยการสนทนาบางอย่างในคำขอดึงความคิดเห็นบน GitHub บางทีคุณอาจจะพบข้อมูลบางอย่างที่นั่น ดู: อัปเดต 2 ในคำตอบของฉัน
rsp

1
ใช่ดูเหมือนว่าพวกเขาเพิ่งแก้ไขปัญหา libuv ล่าสุด ฉันสงสัยว่าเมื่อไหร่ที่ฉันสามารถรับมือกับโมดูลได้ ไม่สามารถรอ! ขอบคุณที่คอยอัพเดท ~ แก้ไข: เพิ่งเริ่มต้น: github.com/petkaantonov/io.js/commit/…เอาล่ะเราจะมาแล้ว!
NiCk Newman

1
ใช่มันอยู่ (ยังไม่มีการนำมาใช้อย่างเป็นทางการ) แต่สามารถดาวน์โหลดแหล่งที่มาได้ที่นี่: github.com/petkaantonov/io.js/tree/…และรวบรวมหากคุณต้องการทดสอบ! ฉันกำลังทำอยู่ ~
NiCk Newman

1
@NiCkNewman ขอบคุณสำหรับข้อมูลใหม่ - ฉันเพิ่มไว้ในคำตอบ
rsp

1
คุณช่วยแจ้งสถานะการworkersใช้งานNode.js ให้เราทราบได้ไหม ความคิดเห็นล่าสุดในPR # 2133มาจากเดือนกุมภาพันธ์ เห็นได้ชัดว่านักพัฒนาประสบปัญหาและไม่มีความคิดเห็นใด ๆ ที่ระบุว่าได้รับการแก้ไขแล้ว
Matheus Moreira

8

ฉันมาจากโรงเรียนเก่าแห่งความคิดที่เราใช้มัลติเธรดเพื่อทำให้ซอฟต์แวร์รวดเร็ว 3 ปีที่ผ่านมาฉันใช้ Node.js และเป็นผู้สนับสนุนรายใหญ่ของมัน ดังที่ hasanyasin ได้อธิบายรายละเอียดวิธีการทำงานของโหนดและแนวคิดของฟังก์ชันการทำงานที่ไม่ตรงกัน แต่ขอฉันเพิ่มบางสิ่งตรงนี้

ย้อนกลับไปในสมัยก่อนที่มีแกนเดี่ยวและความเร็วสัญญาณนาฬิกาต่ำลงเราได้ลองใช้วิธีต่างๆเพื่อให้ซอฟต์แวร์ทำงานได้เร็วและขนานกัน ใน DOS วันเราใช้เพื่อรันทีละโปรแกรม เราเริ่มเรียกใช้แอพพลิเคชั่น (กระบวนการ) หลายตัวพร้อมกันมากกว่าใน windows แนวความคิดเช่นการปรปักษ์และไม่ปรปักษ์ (หรือร่วมมือ) ที่ผ่านการทดสอบ ตอนนี้เรารู้แล้วว่า preemptive เป็นคำตอบสำหรับงานการประมวลผลหลายอย่างที่ดีขึ้นบนคอมพิวเตอร์แกนเดียว แนวคิดของกระบวนการ / งานและการสลับบริบทมาพร้อมกัน กว่าแนวคิดของเธรดเพื่อลดภาระของการสลับบริบทของกระบวนการ ด้ายที่ประกาศเกียรติคุณเป็นทางเลือกที่มีน้ำหนักเบาสำหรับการวางไข่กระบวนการใหม่

ดังนั้นชอบหรือไม่ส่งสัญญาณเธรดหรือไม่ใช่แบบมัลติคอร์หรือคอร์เดียวกระบวนการของคุณจะถูกตัดทอนและแบ่งเวลาโดยระบบปฏิบัติการ

Nodejs เป็นกระบวนการเดียวและมีกลไก async ที่นี่งานจะถูกส่งไปที่ภายใต้ OS ที่โกหกเพื่อดำเนินการในขณะที่เรารอในห่วงเหตุการณ์เพื่อให้งานเสร็จสิ้น เมื่อเราได้รับสัญญาณสีเขียวจาก OS เราจะดำเนินการในสิ่งที่ต้องทำ ในลักษณะนี้เป็นการทำงานแบบมัลติทาสกิ้งแบบร่วมมือ / ไม่ได้รับการป้องกันดังนั้นเราจึงไม่ควรปิดกั้นการวนซ้ำของเหตุการณ์เป็นเวลานานพอสมควรเพราะเราจะลดระดับแอปพลิเคชันของเราอย่างรวดเร็ว
ดังนั้นหากเคยมีงานที่ปิดกั้นโดยธรรมชาติหรือใช้เวลานานมากเราจะต้องแยกมันออกไปสู่โลกของระบบปฏิบัติการและเธรดที่มีการต่อต้าน มีตัวอย่างที่ดีของนี้อยู่ในเอกสาร libuv นอกจากนี้ถ้าคุณอ่านเอกสารต่อไปที่คุณพบว่าFileI / O การจัดการในหัวข้อใน Node.js

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

ภายใต้ฮูดใน node.js เป็น c ++ และเธรดทั้งหมด และโหนดให้วิธี c ++ ในการขยายฟังก์ชันการทำงานและเพิ่มความเร็วให้มากขึ้นโดยใช้เธรดที่จำเป็นเช่นการบล็อกงานเช่นการอ่านจากการเขียนต้นทางไปยังแหล่งที่มาการวิเคราะห์ข้อมูลขนาดใหญ่เป็นต้น

ฉันรู้ว่าคำตอบของ hasanyasin เป็นคำตอบที่ได้รับการยอมรับ แต่สำหรับฉันเธรดจะมีอยู่ไม่ว่าคุณจะพูดอะไรหรือคุณซ่อนไว้หลังสคริปต์อย่างไรประการที่สองไม่มีใครแบ่งสิ่งต่างๆในเธรดเพียงเพื่อความรวดเร็วส่วนใหญ่จะทำเพื่อบล็อกงาน และเธรดอยู่ในกระดูกหลังของ Node.js ดังนั้นก่อนที่จะทุบตีมัลติเธรดอย่างสมบูรณ์จะถูกต้อง นอกจากนี้เธรดยังแตกต่างจากกระบวนการและข้อ จำกัด ของการมีโหนดโปรเซสต่อคอร์ไม่ตรงกับจำนวนเธรดเธรดก็เหมือนกับงานย่อยของโปรเซส ในความเป็นจริงเธรดจะไม่ปรากฏในตัวจัดการงาน windows ของคุณหรือคำสั่งบน linux อีกครั้งที่พวกเขามีน้ำหนักมากขึ้นเล็กน้อยจากนั้นประมวลผล


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

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

4

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


3
สำหรับข้อมูลของคุณผู้ทำงานบนเว็บได้รับการดัดแปลง (บางส่วน) บน node.js และมีจำหน่ายเป็นnode-workersแพ็คเกจ ดูสิ่งนี้: github.com/cramforce/node-worker
Parth Thakkar

สิ่งที่ควรทราบขอบคุณ แม้ว่าเอกสารจะหายากมาก แต่ฉันไม่รู้ว่ามันทำงานในเธรดแยกกันกระบวนการหรือเพียงแค่ทำงานในกระบวนการเดียวกันและฉันไม่มีเวลาขุดลงไปในโค้ดดังนั้นฉันจึงไม่รู้ว่ามันจะ ทำงานในกรณีของคุณ
lanzz

@ParthThakkar: โครงการนั้นไม่ได้รับการสัมผัสใน 3 ปี (2 เมื่อคุณโพสต์) และยังไม่ผ่าน 0.0.1
mpen

@ มาร์ค: สาเหตุที่ผมไม่รู้ก็คือผมยังไม่ได้เป็นโปรแกรมเมอร์มืออาชีพ ห่าฉันไม่ได้อยู่ในมหาวิทยาลัยด้วยซ้ำ ฉันยังคงเป็นเพื่อนโรงเรียนมัธยมที่อ่านเกี่ยวกับการเขียนโปรแกรมอยู่ตลอดเวลา - นอกเหนือจากการจัดการงานของโรงเรียน ดังนั้นจึงเป็นไปไม่ได้ที่ฉันจะมีความรู้เกี่ยวกับปัญหาดังกล่าวจากระยะไกล ฉันเพิ่งโพสต์สิ่งที่ฉันรู้ ...
Parth Thakkar

@ มาร์ค: แม้ว่าคุณจะรู้สึกดีที่ได้ชี้ให้เห็นถึงความเป็นมาของโครงการ สิ่งเหล่านี้จะได้รับการดูแลในการตอบสนองในอนาคตของฉัน !! :)
Parth Thakkar

3

worker_threadsได้รับการติดตั้งและจัดส่งหลังธงในnode@10.5.0. ยังคงเป็นการใช้งานครั้งแรกและจำเป็นต้องใช้ความพยายามมากขึ้นเพื่อให้มีประสิทธิภาพมากขึ้นในการเผยแพร่ในอนาคต nodeคุ้มค่าให้มันลองในล่าสุด


2

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

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

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

หากคุณไม่จำเป็นต้องกังวลเกี่ยวกับสิ่งที่ async และมีความสนใจในการประมวลผลจำนวนมากโดยไม่ต้องปิดกั้นคุณสามารถเรียกใช้การประมวลผลแบบง่ายๆได้ NextTick (โทรกลับ) ทุก ๆ ครั้งเป็นสิ่งที่คุณต้องการ


คำแนะนำของคุณ - เกี่ยวกับคลัสเตอร์ - คือสิ่งที่ฉันคิดในตอนแรก แต่ปัญหาคือค่าใช้จ่ายของพวกเขา - ต้องเริ่มต้นอินสแตนซ์ใหม่ของ v8 ทุกครั้งที่มีการแยกกระบวนการใหม่ (~ 30ms, 10MB) ดังนั้นคุณไม่สามารถสร้างจำนวนมากได้ สิ่งนี้นำมาจากเอกสารโหนดโดยตรง: โหนดลูกเหล่านี้ (เกี่ยวกับ child_processes) ยังคงเป็นอินสแตนซ์ใหม่ทั้งหมดของ V8 สมมติว่าเริ่มต้นอย่างน้อย 30ms และหน่วยความจำ 10mb สำหรับแต่ละโหนดใหม่ นั่นคือคุณไม่สามารถสร้างจำนวนมากได้
Parth Thakkar

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

1

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

หลังจากพูดทั้งหมดนั้นฉันได้ทำงานหลายอย่างกับHook.ioเมื่อไม่นานมานี้ซึ่งดูเหมือนว่าจะทำงานได้ดีมากสำหรับงานที่ไม่โหลดประเภทนี้ในกระบวนการอื่น ๆ บางทีมันอาจจะสามารถบรรลุสิ่งที่คุณต้องการได้

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