한국어English日本語简体中文繁體中文DeutschไทยTiếng ViệtРусскийPortuguês (Brasil)EspañolBahasa Indonesia

คู่มือเกมแลค › L8 ซ็อกเก็ตและโปรโตคอล

การส่งแบบ blocking เพราะไคลเอนต์ช้า Blocking send on a full socket

ID สาเหตุ sk-block-send · ผู้รับผิดชอบหลัก พัฒนาเซิร์ฟเวอร์ (ทีมพัฒนาเกม)

เปิดการ์ดในฉบับหลักที่มีภาพและการทดลอง →

ถ้า send buffer ของผู้เล่นคนหนึ่งที่เน็ตช้าเต็ม แล้วเซิร์ฟเวอร์ส่งแบบ blocking (การส่งที่ฟังก์ชันจะไม่คืนค่าจนกว่าบัฟเฟอร์จะมีที่ว่าง) เธรดของเซิร์ฟเวอร์จะต้องรอผู้เล่นคนนั้นคนเดียว

ทำไม send buffer ของไคลเอนต์ที่ช้าเต็ม → ผลคือ เป็นการส่งแบบ blocking เธรดของเซิร์ฟเวอร์จึงรอจนบัฟเฟอร์มีที่ว่าง → บนหน้าจอ ทุกคนที่เธรดนั้นดูแลค้างหรือเป็นสโลว์โมชั่น

อาการ
ค้าง, สโลว์โมชั่น
ปัจจัย
การหยุดชะงัก
ใครเจอ
บางจุด/บางแชนแนล, ทั้งเซิร์ฟเวอร์
เกิดเมื่อไร
สุ่มเป็นครั้งคราว, ตอนคนแห่มารวมกัน
ผู้รับผิดชอบ
ผู้รับผิดชอบหลัก พัฒนาเซิร์ฟเวอร์ (ทีมพัฒนาเกม)
งานฝั่งทีมพัฒนาเกม
ใช้การส่งแบบ non-blocking, จำกัดความยาวคิวส่งของแต่ละไคลเอนต์, ทิ้งอัปเดตที่เก่าแล้ว
บนกราฟ
พุ่งแบบสุ่มเป็นครั้งคราว · เวลาต่อทิกของเซิร์ฟเวอร์, Send-Q ต่อการเชื่อมต่อ
จุดที่ต้องดู
หาการเชื่อมต่อที่ Send-Q (ไบต์ที่ยังไม่ได้รับ ACK หรือยังไม่ได้ส่ง) เต็มเท่าขนาด send buffer ด้วย ss -tn และดู thread dump (stack) ของเซิร์ฟเวอร์เกมตอนที่ทิกพุ่งว่ามีเธรดที่หยุดอยู่ใน send หรือไม่
สัญญาณว่าใช่
ขณะที่มีการเชื่อมต่อช้าที่ Send-Q เต็ม เธรดที่ดูแลการเชื่อมต่อนั้นหยุดอยู่ใน send และเฉพาะคนที่อยู่ในเธรดเดียวกันเท่านั้นที่หยุดไปด้วย
สัญญาณว่าไม่ใช่
เธรดที่หยุดรออยู่นอก send (ล็อก, การเรียก DB): ให้ดู “การแย่งล็อก”, “synchronous call บนเธรดเกม”
วิธีตรวจ
ใช้เครื่องมือฝั่งอินฟรา (ไม่ต้องใช้โค้ดเกม)

แหล่งอ้างอิง

  1. send(2) — Linux manual page Linux man-pages
    ถ้า send buffer ไม่มีที่ว่าง send() จะถูกบล็อก ส่วนโหมด non-blocking จะคืนค่า EAGAIN ทันที
  2. send function (winsock2.h) Microsoft
    Winsock ก็เช่นกัน ถ้าพื้นที่บัฟเฟอร์ไม่พอ send จะถูกบล็อก เว้นแต่อยู่ในโหมด non-blocking
  3. net/ipv4/tcp_diag.c (Linux v6.12) Linux kernel
    ค่า Recv-Q และ Send-Q ของ ss: ซ็อกเก็ตที่ listen อยู่คือจำนวนการเชื่อมต่อที่รอ accept และขีดจำกัด backlog, ซ็อกเก็ตที่เชื่อมต่อแล้วคือไบต์ที่แอปยังไม่ได้อ่าน และไบต์ที่ส่งไปแล้วแต่ยังไม่ได้รับ ACK

สาเหตุที่ควรดูประกอบ

ชั้นเดียวกัน: L8 ซ็อกเก็ตและโปรโตคอล

สาเหตุจากชั้นอื่นที่ทำให้เกิดอาการเดียวกัน (ค้าง)

ดูการ์ดในฉบับหลักที่มีภาพและการทดลอง