โดยทั่วไปแล้ว Node.js จัดการกับ 10,000 คำขอพร้อมกันอย่างไร


394

ฉันเข้าใจว่า Node.js ใช้เธรดเดี่ยวและวนรอบเหตุการณ์เพื่อประมวลผลคำขอเพียงครั้งละหนึ่งการประมวลผล (ซึ่งไม่ใช่การปิดกั้น) แต่ถึงกระนั้นการทำงานยังไงก็บอกว่า 10,000 คำร้องขอพร้อมกัน ห่วงเหตุการณ์จะดำเนินการตามคำขอทั้งหมดหรือไม่ จะไม่ใช้เวลานานเกินไป?

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

และขนาดด้ายเดี่ยวจะดีหรือไม่กับจำนวนมาก? โปรดจำไว้ว่าฉันเพิ่งเริ่มเรียนรู้ Node.js


5
เพราะงานส่วนใหญ่ (ย้ายข้อมูลไปรอบ ๆ ) ไม่เกี่ยวข้องกับ CPU
OrangeDog

5
โปรดทราบว่าเนื่องจากมีเพียงหนึ่งเธรดที่กำลังเรียกใช้งาน Javascript ไม่ได้หมายความว่าไม่มีเธรดอื่น ๆ อีกมากมายที่ทำงานได้
OrangeDog

คำถามนี้กว้างเกินไปหรือซ้ำซ้อนกับคำถามอื่น ๆ
OrangeDog


พร้อมกับเธรดเดียว Node.js ทำบางสิ่งที่เรียกว่า "ไม่ใช่การบล็อก I / O" ที่นี่คือที่ที่ความมหัศจรรย์ทั้งหมดเสร็จสิ้น
อานันท์ N

คำตอบ:


762

หากคุณต้องถามคำถามนี้แสดงว่าคุณอาจไม่คุ้นเคยกับสิ่งที่เว็บแอปพลิเคชัน / บริการส่วนใหญ่ทำ คุณอาจกำลังคิดว่าซอฟต์แวร์ทั้งหมดทำสิ่งนี้:

user do an action
       
       v
 application start processing action
   └──> loop ...
          └──> busy processing
 end loop
   └──> send result to user

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

user do an action
       
       v
 application start processing action
   └──> make database request
          └──> do nothing until request completes
 request complete
   └──> send result to user

ในสถานการณ์สมมตินี้ซอฟต์แวร์ใช้เวลาส่วนใหญ่ในการทำงานโดยใช้เวลา CPU 0% ที่รอให้ฐานข้อมูลส่งคืน

แอพเครือข่ายแบบมัลติเธรด:

แอพเครือข่ายแบบมัลติเธรดจัดการกับปริมาณงานด้านบนดังนี้:

request ──> spawn thread
              └──> wait for database request
                     └──> answer request
request ──> spawn thread
              └──> wait for database request
                     └──> answer request
request ──> spawn thread
              └──> wait for database request
                     └──> answer request

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

วนรอบเหตุการณ์แบบเธรดเดี่ยว

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

request ──> make database request
request ──> make database request
request ──> make database request
database request complete ──> send response
database request complete ──> send response
database request complete ──> send response

ในทางปฏิบัติทั้งสองวิธีจะส่งคืนข้อมูลโดยมีเวลาแฝงเท่ากันเนื่องจากเป็นเวลาตอบสนองฐานข้อมูลที่ใช้ในการประมวลผล

ข้อได้เปรียบหลักที่นี่คือเราไม่จำเป็นต้องวางไข่เธรดใหม่ดังนั้นเราจึงไม่จำเป็นต้องทำ malloc จำนวนมากซึ่งจะทำให้เราช้าลง

เธรดวิเศษที่มองไม่เห็น

สิ่งลึกลับที่ดูเหมือนจะเป็นวิธีการทั้งสองวิธีข้างต้นจัดการเพื่อให้ปริมาณงานใน "ขนาน"? คำตอบคือฐานข้อมูลเป็นเธรด ดังนั้นแอพพลิเคชั่นเธรดเดี่ยวของเราจึงใช้ประโยชน์จากพฤติกรรมแบบมัลติเธรดของกระบวนการอื่น: ฐานข้อมูล

ตำแหน่งที่เธรดเดี่ยวล้มเหลว

แอพที่มีเธรดเดียวล้มเหลวใหญ่ถ้าคุณต้องการคำนวณ CPU จำนวนมากก่อนส่งคืนข้อมูล ตอนนี้ฉันไม่ได้หมายถึงการประมวลผลลูปสำหรับฐานข้อมูล ส่วนใหญ่ยังคงเป็น O (n) สิ่งที่ฉันหมายถึงคือการแปลงฟูริเยร์ (เช่นการเข้ารหัส MP3), การติดตามเรย์ (การเรนเดอร์ 3D) เป็นต้น

ข้อผิดพลาดอีกประการหนึ่งของแอพพลิเคชั่นที่มีเธรดเดียวคือมันจะใช้ CPU แกนเดียว ดังนั้นหากคุณมีเซิร์ฟเวอร์ quad-core (ไม่ใช่เรื่องแปลกในปัจจุบัน) คุณไม่ได้ใช้ 3 คอร์อื่น

ที่วิธีการแบบมัลติเธรดล้มเหลว

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

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

ดังนั้นหากคุณเขียนแอปเครือข่ายใน C หรือ go หรือ java ค่าใช้จ่ายในการทำเกลียวมักจะไม่เลวร้ายเกินไป หากคุณกำลังเขียนเว็บเซิร์ฟเวอร์ C เพื่อให้บริการ PHP หรือ Ruby คุณสามารถเขียนเซิร์ฟเวอร์ได้เร็วขึ้นใน javascript หรือ Ruby หรือ Python

วิธีไฮบริด

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

สถาปัตยกรรมแบบเธรดเดียวบางตัวยังใช้วิธีไฮบริด แทนที่จะเปิดใช้หลายเธรดจากกระบวนการเดียวคุณสามารถเปิดใช้งานหลายแอปพลิเคชัน - ตัวอย่างเช่นเซิร์ฟเวอร์ 4 node.js บนเครื่อง quad-core จากนั้นคุณใช้ตัวโหลดบาลานซ์เพื่อกระจายเวิร์กโหลดระหว่างกระบวนการ

ในทางปฏิบัติทั้งสองวิธีจะมีภาพสะท้อนเหมือนกันในทางเทคนิคของกันและกัน


105
นี่คือคำอธิบายที่ดีที่สุดสำหรับโหนดที่ฉันอ่านมา ว่า "แอพพลิเคชั่นเธรดเดียวใช้ประโยชน์จากพฤติกรรมแบบมัลติเธรดของกระบวนการอื่น: ฐานข้อมูล" ทำงานได้
kenobiwan

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

3
@CainainCaldion มันขึ้นอยู่กับสิ่งที่คุณหมายถึงโดยลูกค้ามากและรวดเร็ว ตามที่เป็นอยู่ node.js สามารถประมวลผลได้มากกว่า 1,000 คำขอต่อวินาทีและความเร็ว จำกัด เฉพาะความเร็วของการ์ดเครือข่ายของคุณ โปรดทราบว่ามันมี 1,000 คำขอต่อวินาทีไม่ใช่ไคลเอนต์ที่เชื่อมต่อพร้อมกัน มันสามารถจัดการกับ 10,000 ไคลเอ็นต์พร้อมกันโดยไม่มีปัญหา คอขวดที่แท้จริงคือการ์ดเครือข่าย
slebetman

1
@slebetman คำอธิบายที่ดีที่สุดที่เคยมีมา สิ่งหนึ่งที่แม้ว่าถ้าฉันมีอัลกอริทึมการเรียนรู้ของเครื่องจักรซึ่งประมวลผลข้อมูลบางส่วนและให้ผลลัพธ์ตามนั้นฉันควรใช้วิธีการหลายเธรดหรือเธรดเดี่ยว
Ganesh Karewad

5
@GaneshKarewad Algorithms ใช้ CPU, บริการ (ฐานข้อมูล, REST API และอื่น ๆ ) ใช้ I / O หาก AI เป็นอัลกอริธึมที่เขียนด้วย js คุณควรรันในเธรดหรือกระบวนการอื่น หาก AI เป็นบริการที่ทำงานบนคอมพิวเตอร์เครื่องอื่น (เช่นบริการ Amazon หรือ Google หรือ IBM AI) ให้ใช้สถาปัตยกรรมเธรดเดี่ยว
slebetman

46

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

โดยวิธีการเปรียบเทียบคิดว่า NodeJS เป็นบริกรรับการสั่งซื้อของลูกค้าในขณะที่พ่อครัว I / O เตรียมพวกเขาในห้องครัว ระบบอื่น ๆ มีเชฟหลายคนที่สั่งอาหารให้ลูกค้าเตรียมอาหารล้างโต๊ะและเข้าร่วมลูกค้ารายต่อไปเท่านั้น


5
ขอบคุณสำหรับการเปรียบเทียบร้านอาหาร! ฉันพบว่าการเปรียบเทียบและตัวอย่างจากโลกแห่งความจริงนั้นง่ายต่อการเรียนรู้มากขึ้น
LaVache

13

ฉันเข้าใจว่า Node.js ใช้เธรดเดี่ยวและวนรอบเหตุการณ์เพื่อประมวลผลคำขอเพียงครั้งละหนึ่งการประมวลผล (ซึ่งไม่ใช่การปิดกั้น)

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

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

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

ในแต่ละขั้นตอนเหล่านี้ส่วนใหญ่ใช้เวลารอข้อมูลบางอย่างมาถึงปลายอีกด้าน - เวลาจริงที่ใช้ในการประมวลผลในเธรด JS หลักมักจะมีขนาดค่อนข้างน้อย

เมื่อสถานะของวัตถุ I / O (เช่นการเชื่อมต่อเครือข่าย) เปลี่ยนแปลงเช่นนั้นต้องการการประมวลผล (เช่นรับข้อมูลบนซ็อกเก็ตซ็อกเก็ตกลายเป็นเขียนได้ ฯลฯ ) เธรดหลักของ Node.js JS จะถูกปลุกด้วยรายการ ของรายการที่ต้องดำเนินการ

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

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

จุดสำคัญคือการประมวลผลคำขอที่แตกต่างกันนั้นไม่ได้ดำเนินการตามคำขอตั้งแต่ต้นจนจบและย้ายไปยังคำขอถัดไป

ในใจของฉันข้อดีหลักของเรื่องนี้คือคำขอที่ช้า (เช่นคุณกำลังพยายามส่งข้อมูลการตอบสนอง 1MB ไปยังอุปกรณ์โทรศัพท์มือถือผ่านการเชื่อมต่อข้อมูล 2G หรือคุณกำลังทำแบบสอบถามฐานข้อมูลที่ช้ามาก ๆ ) จะได้รับรางวัล ' t บล็อกได้เร็วขึ้น

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

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

ฉันจะไม่อ้างว่าระบบตามเหตุการณ์นั้นเร็วกว่าในทุกสถานการณ์หรือกับทุกภาระงาน - พวกเขามักจะทำงานได้ดีสำหรับ I / O-bound workloads ซึ่งไม่ค่อยดีสำหรับ CPU-bound


12

ขั้นตอนการประมวลผลโมเดลลูปเหตุการณ์เธรดเดี่ยว:

  • ลูกค้าส่งคำขอไปยังเว็บเซิร์ฟเวอร์

  • โหนด JS Web Server รักษาพูลเธรด จำกัด ไว้ภายในเพื่อให้บริการกับคำขอของไคลเอ็นต์

  • โหนด JS Web Server ได้รับการร้องขอเหล่านั้นและวางลงในคิว เป็นที่รู้จักกันในชื่อ“ Event Queue”

  • โหนด JS Web Server ภายในมีส่วนประกอบเรียกว่า "Event Loop" ทำไมมันถึงได้ชื่อนี้คือมันใช้วงวนไม่ จำกัด เพื่อรับคำขอและประมวลผลคำขอ

  • Event Loop ใช้ Single Thread เท่านั้น เป็นหัวใจหลักของโมเดลการประมวลผลแพลตฟอร์ม JS

  • Event Loop ตรวจสอบคำขอของลูกค้าที่อยู่ใน Event Queue ถ้าไม่เช่นนั้นรอคำขอเข้ามาอย่างไม่มีกำหนด

  • ถ้าใช่ให้รับคำขอของลูกค้าหนึ่งรายการจากคิวกิจกรรม

    1. เริ่มกระบวนการที่ลูกค้าร้องขอ
    2. หากคำขอของลูกค้านั้นไม่ต้องการการดำเนินการ Blocking IO ให้ดำเนินการทุกอย่างเตรียมการตอบสนองและส่งกลับไปยังลูกค้า
    3. หากคำขอไคลเอนต์นั้นต้องการการดำเนินการ Blocking IO บางอย่างเช่นการโต้ตอบกับฐานข้อมูลระบบไฟล์บริการภายนอกจากนั้นจะปฏิบัติตามแนวทางที่แตกต่างกัน
  • ตรวจสอบความพร้อมใช้งานของเธรดจากเธรดภายใน
  • เลือกหนึ่งเธรดและกำหนดคำขอไคลเอ็นต์นี้ให้กับเธรดนั้น
  • เธรดนั้นรับผิดชอบการร้องขอประมวลผลดำเนินการบล็อก IO การเตรียมการตอบสนองและส่งกลับไปที่ลูปเหตุการณ์

    คำอธิบายที่ดีมากโดย @Rambabu Posa สำหรับคำอธิบายเพิ่มเติมไปที่ลิงค์นี้


ไดอะแกรมที่ระบุไว้ในบล็อกโพสต์นั้นดูเหมือนว่าผิดสิ่งที่พวกเขากล่าวถึงในบทความนั้นไม่ถูกต้องสมบูรณ์
rranj

11

การเพิ่มคำตอบสำหรับ slebetman: เมื่อคุณพูดว่าNode.JSสามารถจัดการคำร้องขอได้ 10,000 คำร้องขอพร้อมกันนั้นเป็นคำร้องขอที่ไม่ปิดกั้นเช่นคำร้องขอเหล่านี้เกี่ยวข้องกับการสืบค้นฐานข้อมูลเป็นหลัก

ภายในevent loopของNode.JSถูกจัดการthread poolที่แต่ละหัวข้อจัดการและห่วงเหตุการณ์ยังคงฟังการร้องขอมากขึ้นหลังจากการมอบหมายงานให้เป็นหนึ่งในหัวข้อของnon-blocking request thread poolเมื่อหนึ่งของด้ายเสร็จงานก็จะส่งสัญญาณไปยังevent loopว่า บริษัท ได้เสร็จสิ้นการ callbackaka Event loopจากนั้นดำเนินการติดต่อกลับและส่งการตอบกลับ

ในขณะที่คุณยังใหม่กับ NodeJS โปรดอ่านเพิ่มเติมเกี่ยวกับnextTickการทำความเข้าใจวิธีการทำงานของลูปของเหตุการณ์ภายใน อ่านบล็อกในhttp://javascriptissexy.comพวกเขามีประโยชน์จริง ๆ สำหรับฉันเมื่อฉันเริ่มต้นด้วย JavaScript / NodeJS


2

การเพิ่มคำตอบของslebetmanเพื่อความชัดเจนยิ่งขึ้นเกี่ยวกับสิ่งที่เกิดขึ้นขณะเรียกใช้งานโค้ด

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

ตอนนี้ที่นี่มาพร้อมกับข้อมูลอื่นที่ไม่ใช่คิวการโทรกลับครั้งเดียว แต่มีหลายคิว

  1. คลิกคิวถัดไป
  2. คิวงานไมโคร
  3. ตัวนับคิว
  4. คิวการติดต่อกลับของ IO (คำขอ, ไฟล์, ops, db ops)
  5. คิวการสำรวจความคิดเห็นของ IO
  6. ตรวจสอบ Phase phase หรือ SetImmediate
  7. คิวตัวจัดการปิด

เมื่อใดก็ตามที่คำขอมารหัสจะถูกดำเนินการตามลำดับการเรียกกลับนี้

มันไม่เหมือนเมื่อมีการร้องขอการบล็อกมันถูกแนบมากับเธรดใหม่ โดยค่าเริ่มต้นมีเพียง 4 เธรด ดังนั้นจึงมีการจัดคิวอื่นที่เกิดขึ้นที่นั่น

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

ทุกอย่างได้รับการจัดคิวตามประเภทของการโทรกลับและประมวลผลตามลำดับที่กล่าวถึงข้างต้น

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