← Blog

งานอัตโนมัติที่รันสองรอบ — บั๊กที่อาการไม่คงที่และหาสาเหตุยากที่สุด

บั๊กที่ไล่หาสาเหตุยากที่สุดไม่ใช่บั๊กที่ทำให้ระบบพัง แต่เป็นบั๊กที่เกิดบ้างไม่เกิดบ้าง

เราเจอบั๊กแบบนั้นในระบบงานอัตโนมัติ และการไล่ปิดมันให้ขาดกลายเป็นงานที่กินเวลาหลายรีลีสติดกัน

อาการ

รายงานที่เข้ามาไม่เหมือนกันเลยสักเรื่อง

  • บางครั้งลูกค้าได้รับการแจ้งเตือนเรื่องเดียวกันสองครั้ง
  • บางครั้งบิลตามรอบถูกสร้างซ้ำ
  • บางครั้งรายการเดิมถูกประมวลผลสองรอบ

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

สาเหตุ

ระบบของเราถูกออกแบบให้บริการทั้งหมดรวมกันอยู่ในกระบวนการเดียวเพื่อประหยัดหน่วยความจำ ระหว่างการเปลี่ยนผ่านนั้น ตัวจัดการงานอัตโนมัติถูกลงทะเบียนไว้สองที่ — ทั้งในกระบวนการรวมและในกระบวนการแยกที่ยังเหลืออยู่

ผลคือมีตัวจัดการงานสองตัวรันพร้อมกัน ต่างคนต่างหยิบงานเดียวกันไปทำ

ทำไมถึงร้ายแรงกว่าที่ฟัง

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

เมื่อสมมติฐานพัง ปัญหาเกิดสองรูปแบบ

1. ผลซ้ำ

งานที่ส่งอีเมล สร้างเอกสาร หรือหักยอด จะทำสิ่งนั้นสองครั้ง

2. แย่งกันทำงาน

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

การเช็คแบบนี้ไม่ได้ผิด มันแค่ไม่ปลอดภัยเมื่อมีคนแข่งกัน และช่องว่างระหว่าง “เช็ค” กับ “ทำ” กว้างแค่เสี้ยววินาที ซึ่งเป็นเหตุผลที่บั๊กเกิดเป็นครั้งคราวเท่านั้น

สิ่งที่เราทำ

ขั้นที่ 1 — แก้ต้นเหตุ

ให้เหลือที่เดียวที่รับผิดชอบการรันงานเบื้องหลัง

ขั้นที่ 2 — ไล่ตรวจทั้งระบบ

เราไม่หยุดที่การแก้จุดที่เจอ แต่ไล่ตรวจทุกส่วนของระบบว่ายังมีที่ไหนอีกที่อาจรันซ้อนกันได้ พบอีก 2 จุดและแก้ไปพร้อมกัน

ขั้นตอนนี้สำคัญกว่าขั้นแรก เพราะบั๊กที่อาการไม่คงที่ ถ้าเหลือไว้แม้จุดเดียวจะกลับมาในเวลาที่คาดไม่ถึง และคราวหน้าจะไม่มีใครนึกถึงสาเหตุนี้แล้วเพราะ “แก้ไปแล้ว”

ขั้นที่ 3 — เปลี่ยนจาก “เช็คแล้วทำ” เป็น “จองแล้วทำ”

สำหรับงานที่กระทบเงินโดยตรงอย่างการสร้างบิลตามรอบ เราไม่พึ่งการที่มีตัวจัดการงานตัวเดียว

เปลี่ยนวิธีทำงานเป็นการจองรายการก่อนลงมือ — ตัวที่จองได้เท่านั้นที่จะสร้างบิล ตัวที่จองไม่ทันจะข้ามไปเอง

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

นี่คือความต่างระหว่าง “แก้ให้ไม่เกิด” กับ “ทำให้เกิดไม่ได้”

สิ่งที่เจอเพิ่มระหว่างทาง

การไล่ตรวจรอบนี้ทำให้เจอปัญหาอื่นในระบบงานอัตโนมัติที่ซ่อนอยู่ด้วยกัน

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

ทั้งสามเรื่องนี้ไม่เกี่ยวกับบั๊กเดิมโดยตรง แต่เจอเพราะการไล่ตรวจแบบเดียวกัน

ทำไมเราถึงเล่าเรื่องนี้

เพราะเราคิดว่าวิธีจัดการกับบั๊กบอกอะไรเกี่ยวกับทีมได้มากกว่าตัวบั๊กเอง

บั๊กนี้แก้ให้หายอาการได้ในบรรทัดเดียว เราเลือกไม่หยุดตรงนั้น แต่ไล่ตรวจทั้งระบบ แล้วเปลี่ยนวิธีทำงานของส่วนที่กระทบเงินให้ผิดพลาดไม่ได้ตั้งแต่แรก

สำหรับระบบที่ลูกค้าใช้จัดการบัญชีและสต๊อกจริง เราคิดว่านั่นคือมาตรฐานขั้นต่ำที่ควรเป็น

Freeable

บริหารจัดการข้อมูลในองค์กร ครบในที่เดียว

ดูรายละเอียด →

อ่านต่อ

Freeable

บั๊กที่เกิดบ้างไม่เกิดบ้าง — เราไม่เพิ่มเวลา เราเอาเวลาออก

เทสต์ของ Freeable แดงหนึ่งครั้งแล้วเขียวตลอด — บันทึกการไล่หาสาเหตุแบบ investigate-first ที่จบลงด้วยการเอานาฬิกาออกจากเทสต์ แทนที่จะเพิ่มเวลาให้มัน

Freeable

ทำไม AI ถึงตอบคำถามธุรกิจของคุณไม่ได้ — บันได 5 ขั้นของการถามข้อมูลเป็นภาษาคน

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

Freeable

backup ที่รายงานว่าสำเร็จ 1,769 ไฟล์ แต่ป้องกันอะไรไม่ได้เลย — 3-2-1 ไม่พอแล้ว

เราเปิดงานสำรองไฟล์เอกสารภาษี มันคัดลอกครบ 1,769 ไฟล์ รายงานล้มเหลว 0 เขียวสนิท แล้วเราพบว่าปลายทางอยู่ดิสก์เดียวกับต้นฉบับ บทความนี้รวมรูปแบบ backup ที่ใช้จริงนอกจาก 3-2-1 และเล่าว่าทำไม "เขียว" ถึงเป็นสิ่งที่ต้องระวังที่สุด