คำแนะนำเกี่ยวกับโมเดลเซิร์ฟเวอร์เครือข่ายหลายการประมวลผล

เผยแพร่แล้ว: 2022-03-11

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

ฉันควรเลือกเซิร์ฟเวอร์เครือข่ายรุ่นใด

บทความนี้มีไว้สำหรับ "โปรแกรมเมอร์ระบบ" เช่น นักพัฒนาส่วนหลังที่จะทำงานกับรายละเอียดระดับล่างของแอปพลิเคชันของตน โดยใช้รหัสเซิร์ฟเวอร์เครือข่าย โดยปกติจะทำใน C ++ หรือ C แม้ว่าในปัจจุบันภาษาและเฟรมเวิร์กที่ทันสมัยส่วนใหญ่จะมีฟังก์ชันการทำงานระดับต่ำที่เหมาะสมพร้อมประสิทธิภาพระดับต่างๆ

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

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

การแบ่งพาร์ติชันแอปพลิเคชัน (เป็นหลายกระบวนการหรือหลายเธรด)

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

งานแอปพลิเคชันเครือข่ายทั่วไปและรุ่นเซิร์ฟเวอร์เครือข่าย

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

  • งาน #1: สร้าง (และทำลายลง) ของการเชื่อมต่อเครือข่าย
  • งาน #2: การสื่อสารเครือข่าย (IO)
  • งาน #3: งานที่มีประโยชน์; กล่าวคือ เพย์โหลดหรือสาเหตุที่แอปพลิเคชั่นมีอยู่

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

  • MP: หลายกระบวนการ
  • SED: กระบวนการเดียว ขับเคลื่อนด้วยเหตุการณ์
  • SEDA: ฉากที่ขับเคลื่อนด้วยเหตุการณ์สถาปัตยกรรม
  • AMPED: ขับเคลื่อนด้วยเหตุการณ์หลายกระบวนการแบบไม่สมมาตร
  • SYMPED: SYMmetric Multi-Process Event-Driven

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

เซิร์ฟเวอร์เครือข่ายแต่ละรุ่นมีคำอธิบายเพิ่มเติมในหัวข้อต่อไปนี้

แบบจำลองหลายกระบวนการ (MP)

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

โมเดล MP ใช้งานได้ง่าย มาก และใช้งานได้จริงมากตราบใดที่จำนวนกระบวนการทั้งหมดยังค่อนข้างต่ำ ต่ำแค่ไหน? คำตอบนั้นขึ้นอยู่กับว่างาน #2 และ #3 เกี่ยวข้องอะไร ตามหลักการทั่วไป สมมติว่าจำนวนกระบวนการหรือเธรดไม่ควรเกินจำนวนคอร์ของ CPU ประมาณสองเท่า เมื่อมีกระบวนการทำงานมากเกินไปในเวลาเดียวกัน ระบบปฏิบัติการมักจะใช้เวลามากเกินไปในการ thrash (เช่น การเล่นกลกระบวนการหรือเธรดรอบ ๆ บนแกน CPU ที่มีอยู่) และโปรแกรมดังกล่าวมักใช้ CPU เกือบทั้งหมด เวลาในโค้ด "sys" (หรือเคอร์เนล) ทำงานที่มีประโยชน์เพียงเล็กน้อย

ข้อดี: ใช้งานง่ายมาก ใช้งานได้ดีตราบใดที่จำนวนการเชื่อมต่อมีน้อย

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

โมเดลที่ขับเคลื่อนด้วยเหตุการณ์ (SPED) แบบกระบวนการเดียว

โมเดลเซิร์ฟเวอร์เครือข่าย SPED ได้รับความนิยมจากแอปพลิเคชันเซิร์ฟเวอร์เครือข่ายที่มีรายละเอียดสูง เช่น Nginx โดยพื้นฐานแล้ว มันทำงานทั้งสามอย่างในกระบวนการเดียวกัน โดยทำมัลติเพล็กซ์ระหว่างกัน เพื่อให้มีประสิทธิภาพ จำเป็นต้องมีฟังก์ชันเคอร์เนลขั้นสูงบางอย่าง เช่น epoll และ kqueue ในโมเดลนี้ โค้ดถูกขับเคลื่อนโดยการเชื่อมต่อขาเข้าและ "เหตุการณ์" ของข้อมูล และใช้ "วนรอบเหตุการณ์" ซึ่งมีลักษณะดังนี้:

  • ถามระบบปฏิบัติการว่ามี "เหตุการณ์" เครือข่ายใหม่หรือไม่ (เช่น การเชื่อมต่อใหม่หรือข้อมูลขาเข้า)
  • หากมีการเชื่อมต่อใหม่ๆ ให้สร้าง (งาน #1)
  • หากมีข้อมูล ให้อ่าน (งาน #2) และดำเนินการตามนั้น (งาน #3)
  • ทำซ้ำจนกว่าเซิร์ฟเวอร์จะออก

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

มีข้อเสียที่สำคัญสองประการของแนวทางนี้:

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

ด้วยเหตุผลเหล่านี้จึงจำเป็นต้องมีโมเดลขั้นสูงกว่านี้

ข้อดี: สามารถทำงานได้อย่างมีประสิทธิภาพสูงและใช้งานง่ายบนระบบปฏิบัติการ (เช่น ต้องการการแทรกแซงของ OS น้อยที่สุด) ต้องการเพียงแกน CPU เดียวเท่านั้น

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

แบบจำลองสถาปัตยกรรมที่ขับเคลื่อนด้วยเหตุการณ์แบบจัดฉาก (SEDA)

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

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

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

ข้อดี: ความฝันสูงสุดของสถาปนิกซอฟต์แวร์: ทุกอย่างถูกแยกออกเป็นโมดูลอิสระอย่างเป็นระเบียบ

จุด ด้อย: ความซับซ้อนสามารถระเบิดได้จากจำนวนโมดูลเท่านั้น และการจัดคิวข้อความยังช้ากว่าการแชร์หน่วยความจำโดยตรงมาก

โมเดล Asymmetric Multi-Process Event-Driven (AMPED)

เซิร์ฟเวอร์เครือข่าย AMPED เป็น SEDA เวอร์ชันฝึกหัดที่ง่ายต่อการสร้างโมเดล มีโมดูลและกระบวนการที่แตกต่างกันไม่มากนัก และมีคิวข้อความไม่มากนัก นี่คือวิธีการทำงาน:

  • ใช้งาน #1 และ #2 ในกระบวนการ "หลัก" เดียว ในรูปแบบ SPED นี่เป็นกระบวนการเดียวที่ทำเครือข่าย IO
  • ใช้งาน #3 ในกระบวนการ "ผู้ปฏิบัติงาน" ที่แยกจากกัน (อาจเริ่มต้นในหลาย ๆ อินสแตนซ์) เชื่อมต่อกับกระบวนการหลักด้วยคิว (หนึ่งคิวต่อกระบวนการ)
  • เมื่อได้รับข้อมูลในกระบวนการ "หลัก" ให้ค้นหากระบวนการของผู้ปฏิบัติงานที่มีการใช้งานน้อยเกินไป (หรือไม่ได้ใช้งาน) และส่งผ่านข้อมูลไปยังคิวข้อความ กระบวนการหลักจะได้รับข้อความโดยกระบวนการเมื่อการตอบสนองพร้อม จากนั้นจึงส่งการตอบกลับไปยังการเชื่อมต่อ

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

ข้อดี: การแยก IO ของเครือข่ายและเพย์โหลดออกอย่างชัดเจน

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

SYmmetric Multi-Process Event-Driven (SYMPED) Model

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

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

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

ข้อดี: ขีดจำกัดการใช้งาน CPU ระดับบนที่เข้มงวด พร้อมจำนวนลูปที่เหมือน SPED ที่ควบคุมได้

ข้อเสีย: เนื่องจากแต่ละโปรเซสมีลูปเหมือน SPED หากงานเพย์โหลดไม่สม่ำเสมอ เวลาแฝงอาจแตกต่างกันไป เช่นเดียวกับโมเดล SPED ปกติ

เคล็ดลับระดับต่ำบางอย่าง

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

  1. หลีกเลี่ยงการจัดสรรหน่วยความจำแบบไดนามิก สำหรับคำอธิบาย เพียงแค่ดูที่โค้ดสำหรับตัวจัดสรรหน่วยความจำยอดนิยม - พวกเขาใช้โครงสร้างข้อมูลที่ซับซ้อน mutexes และมีโค้ดอยู่มากมาย (เช่น jemalloc เช่นโค้ด C ประมาณ 450 KiB!) โมเดลส่วนใหญ่ข้างต้นสามารถนำไปใช้กับเครือข่ายและ/หรือบัฟเฟอร์แบบสแตติก (หรือจัดสรรล่วงหน้า) ได้อย่างสมบูรณ์ ซึ่งจะเปลี่ยนความเป็นเจ้าของระหว่างเธรดเมื่อจำเป็นเท่านั้น
  2. ใช้สูงสุดที่ระบบปฏิบัติการสามารถให้ได้ ระบบปฏิบัติการส่วนใหญ่ยอมให้หลายโพรเซสฟังบนซ็อกเก็ตเดียว และใช้คุณสมบัติที่การเชื่อมต่อจะไม่ได้รับการยอมรับจนกว่าจะได้รับไบต์แรก (หรือแม้แต่คำขอเต็มครั้งแรก!) บนซ็อกเก็ต ใช้ sendfile() ถ้าทำได้
  3. ทำความเข้าใจโปรโตคอลเครือข่ายที่คุณใช้! ตัวอย่างเช่น โดยปกติแล้ว การปิดใช้งานอัลกอริทึมของ Nagle เป็นเรื่องที่สมเหตุสมผล และควรปิดใช้งานการค้างอยู่หากอัตราการเชื่อมต่อ (อีกครั้ง) สูง เรียนรู้เกี่ยวกับอัลกอริธึมการควบคุมความแออัดของ TCP และดูว่าเหมาะสมหรือไม่ที่จะลองใช้อัลกอริธึมที่ใหม่กว่า

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