← กลับไปหน้าบทความ
ขั้นสูง (MarTech)

เวลาตอบเฉลี่ยของ Webhook ดูปกติ แต่ P99 Latency แย่สุด ๆ: วาง Latency Budget ให้ทุกขั้นตอนมีเพดานของตัวเอง

02 ส.ค. 04:23 · อ่าน 3 นาที
เวลาตอบเฉลี่ยของ Webhook ดูปกติ แต่ P99 Latency แย่สุด ๆ: วาง Latency Budget ให้ทุกขั้นตอนมีเพดานของตัวเอง

สรุปสั้น ๆ

ค่า latency เฉลี่ยที่ดูปกติสามารถซ่อนปัญหาได้ง่าย เพราะ event ส่วนใหญ่เร็วมากจนดึงค่าเฉลี่ยลงมา ในขณะที่ event ส่วนน้อย (มักเป็น 1% ท้าย หรือ P99) ช้ากว่าปกติมากจนเกิด timeout จริง การแบ่งงบเวลาของแต่ละขั้นตอนใน pipeline ให้ชัดเจน (latency budget) ช่วยหาจุดที่กินเวลาแฝงได้ตรงจุดกว่าการดูแค่ค่าเฉลี่ยรวม

ทีมหนึ่งที่ผมช่วยตรวจระบบ ภูมิใจนำเสนอว่า เวลาตอบ webhook เฉลี่ยของระบบอยู่ที่ 180 มิลลิวินาที ซึ่งเร็วกว่ามาตรฐานทั่วไปมาก แต่พอผมขอดูกราฟการกระจายตัวของ latency จริง กลับพบว่า 1% ของ event มี latency สูงถึง 4-6 วินาที ซึ่งเกินเวลาที่ LINE กำหนดให้ตอบ webhook พอดี และ 1% นี้คือสาเหตุที่ทำให้เกิด webhook ซ้ำเป็นระยะ ๆ ทั้งที่ทีมไม่เคยรู้ตัวมาก่อนเพราะดูแต่ค่าเฉลี่ย

ค่าเฉลี่ยเป็นตัวเลขที่หลอกได้ง่ายมากในระบบที่มี traffic ไม่สม่ำเสมอ เพราะ event ส่วนใหญ่ที่เร็วมาก (เช่น 50-100 มิลลิวินาที) จะดึงค่าเฉลี่ยรวมลงมาต่ำ จนกลบปัญหาของ event ส่วนน้อยที่ช้าผิดปกติไปหมด ทั้งที่ event ส่วนน้อยนั้นแหละที่สร้างปัญหาจริงให้ระบบ เช่น timeout, webhook ซ้ำ, หรือ event หลุดหายไปเงียบ ๆ

วิธีที่ช่วยให้เห็นปัญหาชัดกว่าค่าเฉลี่ยคือดูที่ P95 และ P99 latency ควบคู่กันเสมอ แล้วแบ่งงบเวลาของแต่ละขั้นตอนใน pipeline ให้ชัดเจนว่าแต่ละส่วนควรใช้เวลาไม่เกินเท่าไหร่ เพื่อหาว่าจุดไหนกินเวลาแฝงเกินงบที่ตั้งไว้

ทำไมค่าเฉลี่ยหลอกได้ ต้องดู P95/P99 ควบคู่กันเสมอ

ค่าเฉลี่ย (average) คำนวณจากผลรวมหารด้วยจำนวน ทำให้ event ส่วนใหญ่ที่เร็วมีอิทธิพลต่อค่าเฉลี่ยมากกว่า event ส่วนน้อยที่ช้ามาก ในทางสถิติ ค่าเฉลี่ยจึงไม่สะท้อน ‘ประสบการณ์ที่แย่ที่สุด’ ที่ผู้ใช้บางส่วนเจอจริง P95 คือค่าที่บอกว่า 95% ของคำขอเร็วกว่าตัวเลขนี้ ส่วน P99 คือ 99% ของคำขอเร็วกว่าตัวเลขนี้ ยิ่งเปอร์เซ็นไทล์สูง ยิ่งสะท้อนกลุ่ม event ที่แย่ที่สุดชัดเจนขึ้น

สำหรับระบบที่รับ webhook จาก LINE การดู P99 สำคัญกว่าค่าเฉลี่ยมาก เพราะ LINE มี timeout ที่ชัดเจน ถ้า event แม้แค่ 1% เกินเวลานั้น มันจะกระตุ้นให้เกิด webhook ซ้ำทันที ซึ่งเป็นต้นเหตุของปัญหาการนับซ้ำที่ระบบต้องมี idempotency key มารองรับอยู่แล้ว การลด P99 latency จึงช่วยลดโอกาสเกิดปัญหานี้ตั้งแต่ต้นทาง

จุดที่แฝงเวลาไว้โดยที่ไม่มีใครสังเกต

  • DNS resolution และ TLS handshake — ถ้าไม่มีการเชื่อมต่อแบบ keep-alive หรือ connection pooling ทุกคำขอต้องเสียเวลาสร้างการเชื่อมต่อใหม่ทุกครั้ง
  • Query ฐานข้อมูลที่ไม่มี index เหมาะสม — ทำงานเร็วตอนข้อมูลน้อย แต่ช้าลงเรื่อย ๆ ตามขนาดตาราง จนกลายเป็นคอขวดที่มองไม่เห็นตอนทดสอบด้วยข้อมูลจำลอง
  • การ hash ข้อมูลจำนวนมากพร้อมกัน — ปกติเร็ว แต่ถ้าเซิร์ฟเวอร์ถูก CPU-bound จากงานอื่นพร้อมกันในช่วงพีค การคำนวณ hash ก็ช้าลงไปด้วย
  • การเรียก API ภายนอกแบบ synchronous ระหว่างทาง — เช่น เรียก service ตรวจสอบเบอร์โทรก่อนแฮช ถ้า service นั้นตอบช้าเป็นครั้งคราว ทั้ง pipeline จะรอตามไปด้วยทุกครั้งที่เกิดขึ้น

ตัวอย่างการแบ่งงบเวลาของแต่ละขั้นตอนใน pipeline (ตัวอย่างกรอบคิด ไม่ใช่ค่ามาตรฐานตายตัว)

ขั้นตอนงบเวลาที่ตั้ง (ตัวอย่าง)สิ่งที่ควรวัด
รับ webhook และตอบ 200 กลับ LINEไม่เกิน 200 มิลลิวินาทีเวลาตั้งแต่รับ request จนตอบกลับ ไม่รวมการประมวลผลจริง
บันทึกงานเข้า queueไม่เกิน 50 มิลลิวินาทีเวลาที่ใช้ insert หรือ push เข้า queue เท่านั้น
Normalize และ hash ข้อมูล (ทำใน worker แยก)ไม่เกิน 300 มิลลิวินาทีเวลารวมของการ normalize และคำนวณ hash ต่อหนึ่ง event
ยิง CAPI และรอ responseไม่เกิน 2 วินาที ก่อนเข้า retryเวลาที่ worker รอ response จากแพลตฟอร์มปลายทาง

เครื่องมือที่ใช้วัด latency แบบแยกเปอร์เซ็นไทล์ได้จริง

เครื่องมือ monitoring ทั่วไปอย่าง Datadog, Grafana ร่วมกับ Prometheus หรือแม้แต่ log platform พื้นฐานส่วนใหญ่รองรับการคำนวณเปอร์เซ็นไทล์อยู่แล้ว จุดสำคัญคือต้องมี instrumentation แยกวัดเวลาของแต่ละขั้นตอนใน pipeline จริง ไม่ใช่วัดแค่เวลารวมตั้งแต่ต้นจนจบ เพราะถ้าวัดแค่ภาพรวม เมื่อ P99 แย่ลง จะไม่รู้ว่าขั้นตอนไหนเป็นต้นเหตุ

วิธีที่ทำได้จริงคือใส่ timestamp เก็บไว้ที่จุดเริ่มและจุดจบของแต่ละขั้นตอนสำคัญ แล้วคำนวณผลต่างส่งเข้าระบบ monitoring แยกเป็น metric ของแต่ละขั้นตอน เมื่อ latency budget ของขั้นตอนไหนเกินเพดานที่ตั้งไว้บ่อยเกินเกณฑ์ ให้ตั้ง alert แจ้งเตือนแยกเป็นรายขั้นตอนไปเลย จะช่วยลดเวลาไล่หาสาเหตุได้มาก

ลด tail latency ด้วยวิธีที่ตรงจุดกว่าการเพิ่ม resource เฉย ๆ

  1. แยกงานที่ไม่จำเป็นต้องเสร็จก่อนตอบ LINE ออกจาก critical path เช่น การบันทึก log รายละเอียดหรือส่งแจ้งเตือนภายใน ย้ายไปทำหลังตอบ 200 แล้วเสมอ
  2. ใช้ connection pooling กับฐานข้อมูลและ external service ที่เรียกบ่อย เพื่อตัดเวลาสร้างการเชื่อมต่อใหม่ทุกครั้งออกไป
  3. ตั้ง timeout ที่สั้นและชัดเจนสำหรับทุกการเรียก external service ระหว่างทาง แล้ว fallback ไปทำงานต่อในโหมดที่ไม่ต้องรอ ถ้า service นั้นไม่สำคัญขนาดต้องบล็อกทั้ง pipeline
  4. ทบทวน query ฐานข้อมูลที่อยู่ใน critical path เป็นระยะ โดยเฉพาะเมื่อขนาดตารางโตขึ้นเรื่อย ๆ เพราะ query ที่เคยเร็วตอนข้อมูลน้อยอาจกลายเป็นคอขวดเมื่อข้อมูลสะสมมากขึ้นตามอายุของระบบ

สรุป

ตัวเลข latency เฉลี่ยที่ดูดีสามารถซ่อนปัญหาที่ร้ายแรงไว้ได้ ถ้าไม่เคยดู P95/P99 ควบคู่กัน ทีมอาจไม่รู้ตัวเลยว่ามี event ส่วนน้อยที่กำลังสร้างปัญหา timeout และ webhook ซ้ำอยู่เงียบ ๆ ในทุกวัน

การแบ่งงบเวลาของแต่ละขั้นตอนใน pipeline ให้ชัดเจน ไม่ใช่แค่เรื่องของประสิทธิภาพ แต่คือเครื่องมือที่ช่วยหาสาเหตุของปัญหาได้ตรงจุดกว่าการวัดแค่เวลารวมทั้งเส้น ซึ่งบอกได้แค่ว่าช้า แต่บอกไม่ได้ว่าช้าตรงไหน

  • ค่าเฉลี่ย latency หลอกได้ง่าย ต้องดู P95/P99 ควบคู่กันเพื่อเห็นกลุ่ม event ที่แย่ที่สุดจริง
  • แฝงเวลาไว้ในจุดที่มองไม่เห็นบ่อย เช่น connection ใหม่ทุกครั้ง, query ไม่มี index, การเรียก external service แบบ synchronous
  • แบ่งงบเวลาของแต่ละขั้นตอนใน pipeline แยกกัน แล้ววัดและตั้ง alert เป็นรายขั้นตอน แทนการดูแค่เวลารวมทั้งเส้น

คำถามที่พบบ่อย

ควรตั้งเป้าดู P95 หรือ P99 ดีกว่ากัน

ทั้งสองมีประโยชน์ต่างกัน P95 ช่วยให้เห็นภาพรวมของประสบการณ์ที่แย่กว่าปกติในระดับกว้าง ส่วน P99 ช่วยจับกลุ่ม event ที่แย่ที่สุดจริง ๆ ซึ่งมักเป็นกลุ่มที่ก่อปัญหา timeout ระบบที่รับ webhook ควรให้ความสำคัญกับ P99 เป็นพิเศษเพราะใกล้เคียงกับเพดาน timeout ที่แพลตฟอร์มต้นทางกำหนดไว้มากกว่า

latency budget ควรตั้งค่าตายตัวหรือปรับตาม traffic

ควรตั้งเป็นเป้าหมายที่ทีมเห็นพ้องร่วมกันตามลักษณะระบบจริง แล้วทบทวนเป็นระยะเมื่อ traffic หรือขนาดข้อมูลเปลี่ยนไปมาก ไม่มีตัวเลขมาตรฐานที่ใช้ได้กับทุกระบบ เพราะขึ้นอยู่กับความซับซ้อนของ pipeline และ infrastructure ที่ใช้งานจริง

P99 latency แย่ แต่ P50 ปกติดี บอกอะไรได้บ้าง

มักบอกว่าปัญหาไม่ได้เกิดกับทุก event แต่เกิดกับกลุ่มย่อยที่มีเงื่อนไขพิเศษ เช่น ข้อมูลบางรูปแบบที่ประมวลผลช้ากว่าปกติ หรือช่วงเวลาที่ resource ถูกแย่งใช้จากงานอื่นพร้อมกัน ควรไล่ดูว่า event กลุ่มที่ช้ามีอะไรร่วมกันแทนที่จะมองภาพรวมทั้งระบบ

เพิ่ม server resource (CPU/RAM) แล้วช่วยลด P99 ได้จริงไหม

ช่วยได้ในบางกรณีที่ปัญหามาจาก resource ไม่พอจริง ๆ แต่ถ้าปัญหามาจาก query ที่ไม่มี index หรือการเรียก external service ที่ตอบช้า การเพิ่ม resource จะไม่ช่วยแก้ที่ต้นเหตุ ควรวัดให้แน่ใจก่อนว่าคอขวดอยู่ตรงไหนจริง ๆ ก่อนตัดสินใจเพิ่ม resource

ทีมเล็กที่ยังไม่มีระบบ monitoring latency แบบละเอียด ควรเริ่มยังไง

เริ่มจากใส่ timestamp เก็บที่จุดเริ่มและจุดจบของขั้นตอนหลัก ๆ เพียงไม่กี่จุดก่อน แล้วส่ง log เข้าไปยังเครื่องมือฟรีอย่าง Grafana Cloud หรือแม้แต่เขียนสคริปต์คำนวณเปอร์เซ็นไทล์เองจาก log ที่มีอยู่ ไม่จำเป็นต้องมีระบบ monitoring ราคาแพงตั้งแต่วันแรก

อยากวัดผลโฆษณาเข้า LINE ให้ถึงยอดขาย?

ทดลองใช้ linli ฟรี 14 วัน ไม่ต้องใช้บัตรเครดิต

เริ่มทดลองใช้ฟรี

บทความที่เกี่ยวข้อง

คู่มือเริ่มต้น LINE Conversion Tracking ในไทย ตั้งแต่ติดตั้งจนวัดยอดขายจริง
คู่มือเริ่มต้น LINE Conversion Tracking ในไทย ตั้งแต่ติดตั้งจนวัดยอดขายจริง
สำหรับคนที่เพิ่งเริ่มทำ LINE Conversion Tracking บทความนี้รวมทุกขั้นตอนตั้งแต่นิยาม Funnel ติดตั้งระบบ เชื่อมแพลตฟอร์ม จนถึงวางแผนช่วงทดลองใช้ให้ตัดสินใจได้จริงก่อนหมด Trial
LINE Tracking กับ PDPA ธุรกิจไทยควรเก็บข้อมูลอย่างไรให้เหมาะสม
LINE Tracking กับ PDPA ธุรกิจไทยควรเก็บข้อมูลอย่างไรให้เหมาะสม
ระบบ Tracking ไม่ได้ทำให้ธุรกิจผ่าน PDPA โดยอัตโนมัติ บทความนี้อธิบายว่าธุรกิจยังต้องรับผิดชอบอะไรเองบ้าง ตั้งแต่ Legal Basis ไปจนถึงการจำกัดข้อมูลที่ส่งไปแพลตฟอร์มโฆษณา
วิธีติดตั้ง Tracking Link และ Tracking Script สำหรับปุ่ม LINE บนเว็บไซต์
วิธีติดตั้ง Tracking Link และ Tracking Script สำหรับปุ่ม LINE บนเว็บไซต์
ก่อนติดตั้ง Tracking Link หรือ Script บนปุ่ม LINE ต้องเตรียมอะไรบ้าง บทความนี้เล่าขั้นตอนจริงตั้งแต่สิทธิ์เข้าถึงเว็บ ไปจนถึง Test Journey ก่อนเปิดใช้งาน ไม่ใช่แค่ก็อปโค้ดไปวาง