𝗕𝘂𝗶𝗹𝗱𝗶𝗻𝗴 𝗮 𝗠𝘂𝗹𝘁𝗶-𝗥𝗲𝗴𝗶𝗼𝗻 𝗛𝗲𝗮𝗹𝘁𝗵-𝗖𝗵𝗲𝗰𝗸 𝗔𝗴𝗴𝗿𝗲𝗴𝗮𝘁𝗼𝗿
ผู้ใช้งานในเซาเปาโล (São Paulo) เข้าถึง edge node ที่ใช้งานไม่ได้ แต่พวกเขาไม่ได้แจ้งรายงานบั๊ก เพียงแค่ปิดแท็บแล้วไปดูอย่างอื่นแทน
ระบบตรวจสอบ uptime ปกติจะตรวจไม่พบเรื่องนี้ เพราะตัวตรวจสอบส่วนใหญ่มักจะส่งสัญญาณจากจุดเดียว ซึ่งจากจุดนั้น ทุกอย่างดูเหมือนจะทำงานปกติ (green)
หน้า status page ของเราเคยแสดงสถานะ uptime 100% ในขณะที่ผู้ใช้งานจริงกลับเจอ timeout การตรวจสอบสถานะ (health check) จากจุดเดียวทั่วโลกกำลังหลอกเราอยู่
และนี่คือวิธีที่เราสร้างระบบที่บอกความจริง
ปัญหา: อคติจากการสุ่มตัวอย่าง (Sampling Bias) หากตัวตรวจสอบของคุณอยู่ในศูนย์ข้อมูล (data center) เพียงแห่งเดียว คุณจะเห็นความจริงเพียงด้านเดียว คุณอาจจะรายงานว่าสถานะปกติ (green) ทั้งที่ edge ในสิงคโปร์และเซาเปาโลกำลังตัดการเชื่อมต่ออยู่
ปริมาณทราฟฟิกวิดีโอทำให้ปัญหานี้แย่ลง ความล้มเหลวในระดับภูมิภาคที่พบบ่อย ได้แก่:
- เส้นทาง BGP ที่ผิดพลาดซึ่งส่งผลกระทบต่อทวีปใดทวีปหนึ่ง
- การล้างแคช (Cache evictions) ที่ทำให้ต้องดึงข้อมูลจากต้นทาง (origin) ซึ่งล่าช้า
- ข้อผิดพลาดของดิสก์ที่ทำให้เกิด TLS handshake timeout
- ปัญหา DNS ที่ตัว resolver เฉพาะในท้องถิ่น
การตอบกลับ "200 OK" เพียงอย่างเดียวแทบไม่ได้บอกอะไรคุณเลย
กฎ 3 ข้อสำหรับสถานะความพร้อมใช้งาน (Health): เราก้าวข้ามการดูแค่ status code โดยเรากำหนดสถานะความพร้อมใช้งานผ่าน 3 ตัวชี้วัด:
- การเข้าถึงได้ (Reachability): การทำ TCP และ TLS handshakes ต้องเสร็จสิ้นภายใน 800ms
- ความหน่วง (Latency): เราติดตามค่า p95 Time-to-First-Byte (TTFB) เพราะค่าเฉลี่ยจะบดบังกลุ่มข้อมูลที่ล่าช้า (slow tail) ซึ่งสร้างความรำคาญให้กับผู้ใช้
- ความถูกต้อง (Correctness): เนื้อหาการตอบกลับ (response body) ต้องมีเครื่องหมาย (marker) ที่คาดหวังไว้ การที่ได้รับ 200 OK แต่กลับเป็นหน้า error ถือว่าล้มเหลว
วิธีแก้ปัญหา: การตรวจสอบแบบหลายภูมิภาค (Multi-Region Probing) เราเลิกใช้ตัวตรวจสอบขนาดใหญ่เพียงตัวเดียว แต่เปลี่ยนมาใช้ Go binaries ขนาดเล็กที่ติดตั้งบน VPS ราคาถูกในภูมิภาคต่างๆ แทน
ตัวตรวจสอบ (prober) แต่ละตัวจะ:
- ตรวจสอบ edge จากมุมมองในพื้นที่นั้นๆ
- ใช้
httptraceเพื่อรับข้อมูล TTFB ที่แท้จริง - ส่งผลลัพธ์ไปยังตัวรวบรวมข้อมูลส่วนกลาง (central aggregator)
เราใช้ SQLite ในการจัดเก็บข้อมูล ซึ่งเรียบง่ายและรองรับภาระงานของเราได้โดยไม่มี overhead มากนัก เราจัดเก็บข้อมูลตัวอย่างดิบ (raw samples) แทนที่จะเป็นข้อมูลที่สรุปผลมาแล้ว เพื่อให้เราสามารถนำมาคำนวณคะแนนย้อนหลังหรือใช้ดีบั๊กความล้มเหลวเฉพาะจุดในภายหลังได้
เคล็ดลับ: ระบบฉันทามติ (Quorum) เครือข่ายมักจะมีสัญญาณรบกวน (noisy) แพ็กเก็ตที่หลุดไปเพียงหนึ่งแพ็กเก็ตไม่ได้หมายความว่าระบบล่ม
เราใช้ระบบ quorum เพื่อป้องกันการแจ้งเตือนที่ผิดพลาด (false alarms) เราจะประกาศว่า edge "ล่ม" (down) ก็ต่อเมื่อหลายภูมิภาคเห็นตรงกันเท่านั้น หากภูมิภาคหนึ่งพบความล้มเหลวแต่ภูมิภาคอื่นไม่พบ เราจะไม่แจ้งเตือนทีมงาน การตัดสินใจออกแบบเช่นนี้ช่วยลดการแจ้งเตือนที่ผิดพลาดลงได้ถึง 90%
บทเรียนสำคัญ:
- ตรวจสอบในจุดที่ผู้ใช้งานเข้าถึงจริง ไม่ใช่แค่เส้นทางจำลอง (synthetic path)
- ติดตามค่า tail latency (p95) ไม่ใช่ค่าเฉลี่ย
- ใช้ prober ราคาถูกที่สามารถเปลี่ยนใหม่ได้ง่ายในหลายๆ ภูมิภาค
- ใช้ระบบ quorum เพื่อหลีกเลี่ยงอาการล้าจากการแจ้งเตือน (pager fatigue)
- รักษาโครงสร้างการจัดเก็บข้อมูล (storage stack) ให้เรียบง่าย
คุณไม่จำเป็นต้องมีแพลตฟอร์ม observability ที่หนักอึ้ง สิ่งที่คุณต้องการคือ local probes, ข้อมูลดิบ และกฎที่ไม่ตื่นตระหนกไปกับ noise