เว็บเซิร์ฟเวอร์จะ“ ฟัง” ที่อยู่ IP ขัดจังหวะหรือหยั่งเสียงอย่างไร


87

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


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

1
@sawdust น่าสนใจมาก คำถามมีขึ้นเพื่อเข้าใจการเชื่อมต่อระหว่างกระบวนการ SW และ HW อย่าง
แท้จริง

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

@ G-Man: ฉันทฤษฎีใช่ ในความเป็นจริงพิมพ์ดีดส่วนใหญ่ไม่พิมพ์ที่ 1 Gbit / s ซึ่งแสดงให้เห็นถึงการมีสองสถาปัตยกรรมที่แตกต่างกัน หนึ่งสะอาดยืดหยุ่นและช้าหนึ่งเงอะงะ แต่ความเร็วสูง
MSalters

คำตอบ:


181

คำตอบสั้น ๆ คือ: ระบบอินเตอร์รัปต์บางประเภท โดยพื้นฐานแล้วพวกเขาใช้การบล็อก I / O ซึ่งหมายความว่าพวกเขาหลับ (บล็อก) ในขณะที่รอข้อมูลใหม่

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

  2. เมื่อมีข้อมูลใหม่เข้ามาในเครือข่ายการ์ดเครือข่ายจะขัดจังหวะการทำงาน

  3. เห็นว่ามีการขัดจังหวะจากการ์ดเครือข่ายเคอร์เนลผ่านไดรเวอร์การ์ดเครือข่ายอ่านข้อมูลใหม่จากการ์ดเครือข่ายและเก็บไว้ในหน่วยความจำ (ต้องดำเนินการอย่างรวดเร็วและจัดการโดยทั่วไปภายในตัวจัดการขัดจังหวะ)

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

  5. ในเวลาว่างเคอร์เนลจะปลุกกระบวนการเว็บเซิร์ฟเวอร์ที่ถูกบล็อก (เนื่องจากสามารถรันได้ในขณะนี้)

  6. กระบวนการเว็บเซิร์ฟเวอร์ดำเนินการต่อราวกับไม่มีเวลาผ่านไป การเรียกระบบการบล็อกของมันจะส่งคืนและประมวลผลข้อมูลใหม่ จากนั้นไปที่ขั้นตอนที่ 1


18
+1 สำหรับการแยกเคอร์เนลกับกระบวนการเว็บเซิร์ฟเวอร์อย่างชัดเจน
Russell Borogove

13
ฉันไม่อยากจะเชื่ออะไรที่ซับซ้อนเท่านี้สรุปได้อย่างชัดเจนและเรียบง่าย แต่คุณก็ทำได้ +1
แบรนดอน

8
+1 คำตอบที่ดี นอกจากนี้ขั้นตอนระหว่าง 2 และ 3 ยังมีความซับซ้อนเพิ่มขึ้นเล็กน้อยด้วย NICs ระบบปฏิบัติการและไดรเวอร์ที่ทันสมัย ตัวอย่างเช่นกับNAPIบน Linux แพ็กเก็ตจะไม่ได้รับจริงในบริบทขัดจังหวะ แต่เคอร์เนลบอกว่า "โอเค NIC ฉันเข้าใจว่าคุณมีข้อมูลออกมาปิดกั้นฉัน (ปิดการใช้งานแหล่งขัดจังหวะ) และฉันจะกลับมาเร็ว ๆ นี้เพื่อคว้าแพ็คเก็ตนี้และแพ็คเก็ตอื่น ๆ
Jonathon Reinhart

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

3
"อ่านข้อมูลใหม่จากการ์ดเครือข่ายและเก็บไว้ในหน่วยความจำ (ต้องทำอย่างรวดเร็วและโดยทั่วไปจะจัดการภายในตัวจัดการขัดจังหวะ)" มันไม่ได้กระทำกับการเข้าถึงหน่วยความจำโดยตรง?
Siyuan Ren

9

มีรายละเอียด "ต่ำ" ค่อนข้างมาก

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

ที่ใดที่หนึ่งในเซิร์ฟเวอร์คือการเรียกของระบบที่ระบุว่า "ให้บางสิ่งบางอย่างแก่ฉัน" มีสองประเภทกว้าง ๆ ของวิธีนี้สามารถทำได้ ในกรณีของ Apache ก็เรียกacceptบนซ็อกเก็ Apache ได้เปิดก่อนหน้านี้อาจจะฟังในพอร์ต 80 เคอร์เนลรักษาคิวของความพยายามในการเชื่อมต่อและเพิ่มลงในคิวที่ทุกครั้งที่TCP SYNจะได้รับ วิธีที่เคอร์เนลรู้ว่าได้รับ TCP SYN นั้นขึ้นอยู่กับไดรเวอร์อุปกรณ์ สำหรับ NIC จำนวนมากอาจมีการขัดจังหวะฮาร์ดแวร์เมื่อได้รับข้อมูลเครือข่าย

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

เมื่อacceptกลับมาแล้ว Apache รู้ว่ามีใครบางคนกำลังพยายามเริ่มต้นการเชื่อมต่อ จากนั้นเรียกใช้forkเพื่อแยกกระบวนการ Apache ออกเป็นสองกระบวนการที่เหมือนกัน หนึ่งในกระบวนการเหล่านี้ดำเนินการตามคำขอ HTTP อีกสายacceptหนึ่งอีกครั้งเพื่อรับการเชื่อมต่อครั้งต่อไป ดังนั้นจึงมีกระบวนการหลักอยู่เสมอซึ่งไม่ทำอะไรเลยนอกจากเรียกacceptกระบวนการย่อยและวางไข่แล้วมีกระบวนการย่อยหนึ่งกระบวนการสำหรับแต่ละคำขอ

นี่คือการทำให้เข้าใจง่าย: เป็นไปได้ที่จะทำเช่นนี้กับเธรดแทนกระบวนการและเป็นไปได้ที่จะทำforkไว้ล่วงหน้าดังนั้นจึงมีกระบวนการของผู้ปฏิบัติงานพร้อมที่จะไปเมื่อได้รับการร้องขอซึ่งจะช่วยลดค่าใช้จ่ายในการเริ่มต้น ทั้งนี้ขึ้นอยู่กับการกำหนดค่า Apache ว่าอาจทำอย่างใดอย่างหนึ่งเหล่านี้

นั่นเป็นหมวดหมู่แรกที่กว้างของวิธีการทำและเรียกว่าการบล็อก IOเพราะระบบเรียกacceptและreadและwriteที่ทำงานบนซ็อกเก็ตจะระงับกระบวนการจนกว่าพวกเขาจะมีสิ่งที่จะกลับมา

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

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

ข้อดีของรุ่นนี้คือคุณต้องการเพียงหนึ่งกระบวนการ ซึ่งหมายความว่าคุณไม่ต้องจัดสรรสแต็กและโครงสร้างเคอร์เนลสำหรับแต่ละคำขอ NginxและHAProxyใช้โมเดลนี้และเป็นเหตุผลใหญ่ที่พวกเขาสามารถจัดการกับการเชื่อมต่อได้มากกว่า Apache บนฮาร์ดแวร์ที่คล้ายกัน

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