เมื่อการเปลี่ยนเวลาไป-กลับมาใกล้วันปีละสองครั้ง ผู้ดูแลระบบก็ต้องเตรียมรับมือกับความไม่แน่นอนที่หลีกเลี่ยงไม่ได้: งาน cron ที่ทำงานไม่เป็นไปตามคาด สิ่งที่ดูเหมือนเป็นงานกำหนดเวลาธรรมดาๆ อาจกลายเป็นปัญหาลูกโซ่ของการทำงานซ้ำหรือการหลุดรอดของงาน สร้างความปวดหัวให้กับทีมไอทีทั่วโลก ชุมชนผู้ใช้ได้มีการพูดคุยกันอย่างต่อเนื่องเกี่ยวกับปัญหาประจำปีนี้และแบ่งปันบทเรียนที่ได้จากประสบการณ์เกี่ยวกับข้อผิดพลาดในการจัดกำหนดการตามเวลา
ปัญหา Cron กับการเปลี่ยนเวลา
ปัญหาหลักอยู่ที่วิธีที่ cron จัดการกับการเปลี่ยนแปลงเวลาปีละสองครั้ง เมื่อนาฬิกาเดินหน้าไปหนึ่งชั่วโมง ช่วงเวลานั้นก็หายไปอย่างมีประสิทธิภาพ ซึ่งอาจทำให้งานที่กำหนดไว้ถูกข้ามไป ในทางกลับกัน เมื่อนาฬิกาถอยหลัง ชั่วโมงเดียวกันนั้นจะเกิดขึ้นสองครั้ง ซึ่งอาจนำไปสู่การที่งานทำงานหลายครั้ง ผู้ดูแลระบบท่านหนึ่งได้แบ่งปันตัวอย่างที่ชัดเจนของปัญหานี้: บน Linux ที่ใช้ vixie-cron เราเห็นงาน cron สองงานทำงานประมาณหนึ่งครั้งต่อวินาทีระหว่างเวลา 3:00 น. ถึง 3:01 น. เมื่อการเปลี่ยนเวลาไป-กลับมาเริ่มขึ้นครั้งล่าสุด ดังนั้นพวกมันจึงทำงานประมาณ 60 ครั้ง และขัดขวางการทำงานของกันและกัน การทำงานซ้ำเช่นนี้อาจทำให้เกิดการแย่งชิงทรัพยากร ความเสียหายของข้อมูล หรือความไม่เสถียรของระบบ ขึ้นอยู่กับว่างานที่กำหนดเวลาไว้กำลังทำอะไรอยู่
ปัญหาไม่ได้จำกัดอยู่ที่การใช้งานเฉพาะใด ๆ — มันเป็นเรื่องพื้นฐานเกี่ยวกับวิธีการที่การจัดกำหนดการตามเวลามีปฏิสัมพันธ์กับการเปลี่ยนแปลงเวลาแบบไม่เป็นเส้นตรง การใช้งาน cron ที่แตกต่างกันจัดการกับกรณีขอบเหล่านี้แตกต่างกันไป โดยบางตัวฉลาดกว่าตัวอื่นๆ ในการตรวจจับและจัดการกับการกระโดดของเวลา
พฤติกรรมทั่วไปของการทำงาน Cron ในช่วง DST:
- Vixie-cron: อาจรันงานหลายครั้งในช่วงการเปลี่ยนแปลง "fall back"
- BusyBox cron: การทำงานแบบเบาที่มีตรรกะ DST น้อยที่สุด
- systemd timers: การจัดการเวลาที่ซับซ้อนมากขึ้นใน Linux distributions สมัยใหม่
ทางออกด้วย UTC และข้อจำกัด
คำแนะนำที่พบบ่อยที่สุดจากผู้ดูแลระบบที่มีประสบการณ์นั้นตรงไปตรงมา: ใช้ UTC สำหรับเวลาของเซิร์ฟเวอร์ทั้งหมด วิธีนี้จะขจัดการเปลี่ยนแปลงเวลาไป-กลับไปเลย เนื่องจากเวลา UTC ไม่มีการเปลี่ยนแปลงตามฤดูกาลเหล่านี้ ดังที่ผู้แสดงความคิดเห็นหนึ่งระบุว่า > แค่ใช้ UTC สิครับ นอกเสียจากคุณมีเหตุผลที่ดีจริงๆ ว่าทำไมไม่ควร วิธีการนี้ทำให้การวิเคราะห์บันทึกง่ายขึ้น ขจัดความคลุมเครือในการจัดกำหนดการ และให้จุดอ้างอิงที่สม่ำเสมอทั่วทั้งระบบแบบกระจาย
อย่างไรก็ตาม UTC ไม่ใช่ทางออกที่ดีสำหรับทุกสถานการณ์การจัดกำหนดการ ข้อกำหนดทางธุรกิจมักกำหนดให้งานต้องทำงานสัมพันธ์กับชั่วโมงทำงานท้องถิ่น รูปแบบกิจกรรมของลูกค้า หรือข้อกำหนดทางกฎหมาย ตัวอย่างเช่น ระบบการเงินอาจต้องการให้รายงานสร้างขึ้นตามวันทำการท้องถิ่น แทนที่จะเป็นวันที่ตาม UTC ผู้ดูแลระบบท่านหนึ่งชี้ให้เห็นข้อจำกัดนี้: ลูกค้าของเราไม่ได้อยู่ใน UTC โดยทั่วไปคนคาดหวังว่าสิ่งต่างๆ เช่น ขีดจำกัดการใช้งานจะถูกรีเซ็ตตอนกลางคืน ไม่ใช่ตอนเที่ยงคืน UTC สิ่งนี้สร้างความตึงเครียดระหว่างความเรียบง่ายทางเทคนิคและข้อกำหนดทางธุรกิจที่แต่ละองค์กรต้องแก้ไขตามความต้องการเฉพาะของตน
ฉันเคยต้องพยายามจัดการความสะอาดหลังจากมีการตัดสินใจแบบเดียวกันนี้แต่ทำแต่แรก และมันเจ็บปวดมาก โปรดใช้ UTC ทั่วทั้งระบบเถอะนะครับ ใครสักคนวันหนึ่งอาจต้องมาจัดการความยุ่งเหยิงของคุณ
กลยุทธ์การจัดกำหนดการทางเลือก
นอกเหนือจากคำแนะนำพื้นฐานเรื่อง UTC แล้ว ชุมชนยังได้พัฒนากลยุทธ์ที่ใช้งานได้จริงหลายประการสำหรับการจัดกำหนดการที่แข็งแกร่ง หลายคนแนะนำให้หลีกเลี่ยงเวลาที่เป็นเลขกลมๆ เช่น ตี 2 ตรง และให้ใช้เวลาที่ไม่ค่อยมีใครใช้ในช่วงนอกชั่วโมงเร่งด่วนแทน เช่น ตี 2 สิบสามนาที หรือ ตี 3 สี่สิบสองนาที สิ่งนี้ไม่เพียงแต่ช่วยหลีกเลี่ยงช่วงเวลาการเปลี่ยนเวลาไป-กลับมาเท่านั้น แต่ยังลดการแย่งชิงทรัพยากรเมื่อหลายระบบอาจกำลังกำหนดเวลางานบำรุงรักษาพร้อมกัน
ผู้ดูแลระบบบางส่วนสนับสนุนให้ใช้ระบบการจัดกำหนดการที่ซับซ้อนมากขึ้นซึ่งเข้าใจความซับซ้อนของเขตเวลาโดยธรรมชาติ ระบบเหล่านี้สามารถจัดการข้อกำหนดทางธุรกิจเช่น รันงานนี้ตอน 8 โมงเช้าตามเวลาท้องถิ่น ในขณะที่จัดการการเปลี่ยนเวลาไป-กลับมาในระดับตัวจัดกำหนดการ แทนที่จะพึ่งพานาฬิกาของระบบพื้นฐาน คนอื่นๆ แนะนำให้สร้างกลไกการป้องกันการทำงานซ้ำและการล็อกโดยตรงลงในงานที่กำหนดเวลาไว้ เพื่อให้แน่ใจว่าแม้งานจะทำงานหลายครั้งก็จะไม่ก่อให้เกิดปัญหา
สำหรับผู้ที่ยังต้องใช้ cron แบบดั้งเดิม วิธีแก้ไขชั่วคราวที่ใช้งานได้จริงรวมถึงการใช้เครื่องมือเช่น flock เพื่อป้องกันการทำงานที่ทับซ้อนกัน หรือการนำตรรกะที่กำหนดเองมาใช้ภายในสคริปต์เพื่อตรวจสอบว่าพวกมันได้ทำงานไปแล้วเมื่อไม่นานมานี้ บางคน甚至กำหนดเวลารายการซ้ำโดยเฉพาะสำหรับวันที่มีปัญหา แม้ว่าวิธีนี้จะต้องมีการบำรุงรักษาด้วยตนเองและมีความเสี่ยงในตัวเอง
แนวทางปฏิบัติที่แนะนำสำหรับการกำหนดตารางเวลา:
- ใช้ UTC สำหรับเขตเวลาของเซิร์ฟเวอร์เมื่อเป็นไปได้
- หลีกเลี่ยงการกำหนดตารางเวลาที่ 2:00 AM และ 3:00 AM ในเขตเวลาที่มี DST
- พิจารณาการกำหนดตารางเวลาแบบนาทีคี่ (เช่น 2:13 AM แทนที่จะเป็น 2:00 AM)
- ใช้งานการล็อคงานด้วยเครื่องมืออย่าง
flock - สร้างความเป็น idempotence ให้กับงานที่กำหนดตารางเวลาไว้
ปัจจัยมนุษย์ในการจัดการเวลา
การอภิปรายมักจะวนกลับมาที่ความแปลกประหลาดพื้นฐานของเวลาไป-กลับมาเอง ผู้เชี่ยวชาญด้านเทคนิคหลายคนมองว่ามันเป็นความซับซ้อนที่ไม่จำเป็นที่สร้างปัญหาที่ไกลเกินกว่าการจัดกำหนดการ cron การเปลี่ยนแปลงเวลาปีละสองครั้งมีการเชื่อมโยงกับความผิดพลาด อุบัติเหตุ และปัญหาสุขภาพที่เพิ่มขึ้น ซึ่งนำไปสู่การเรียกร้องให้ยกเลิกการปฏิบัตินี้ทั้งหมด
ในขณะเดียวกัน ผู้ดูแลระบบก็พัฒนากลยุทธ์ส่วนตัวสำหรับการจัดการความซับซ้อนของเขตเวลา บางคนใช้นาฬิกา UTC บนโต๊ะทำงาน ในขณะที่บางคนเก็บแผ่นอ้างอิงแสดงออฟเซตปัจจุบันสำหรับเขตเวลาต่างๆ ข้อสรุปคือการจัดการเวลาต้องการทั้งโซลูชันทางเทคนิคและความตระหนักของมนุษย์ — ไม่มีอะไรมาทดแทนความเข้าใจในความซับซ้อนของระบบที่คุณกำลังจัดการได้
ในขณะที่เรายังคงดำเนินงานในภูมิทัศน์ทางเทคนิคที่เชื่อมโยงถึงกันและเป็นโลกาภิวัตน์มากขึ้น การจัดการเวลาที่แข็งแกร่งยังคงมีความสำคัญอย่างยิ่ง ไม่ว่าจะผ่านการนำ UTC มาใช้ เครื่องมือการจัดกำหนดการที่ฉลาดขึ้น หรือการวางแผนอย่างรอบคอบรอบๆ การเปลี่ยนเวลาไป-กลับมา เป้าหมายยังคงเหมือนเดิม: การรับประกันว่างานที่กำหนดเวลาไว้จะทำงานเมื่อควรทำงาน ครบตามจำนวนครั้งที่ควรทำงาน โดยไม่คำนึงถึงความต้องการเปลี่ยนแปลงตามฤดูกาลของเวลา
อ้างอิง: Avoid 2:00 and 3:00 am cron jobs!
