วิธีอ่าน Cron expression ทีละช่อง
Cron expression คือบรรทัดข้อความสั้นๆ ที่บอก scheduler ว่าควรรันงานเมื่อไหร่ รูปแบบที่ใช้กันทั่วไปมี 5 ช่อง คั่นด้วยเว้นวรรค ได้แก่ นาที ชั่วโมง วันที่ของเดือน เดือน และวันในสัปดาห์ บรรทัด 0 9 * * 1-5 หมายถึง 09:00 ตั้งแต่วันจันทร์ถึงวันศุกร์ แต่ละช่องเป็นตัวเลข ชื่อ รายการ ช่วง หรือ step หรือ * ซึ่งหมายถึงทุกค่า และงานจะรันในเวลาที่ทุกช่องตรงกันพร้อมกัน
5 ช่อง
| ช่อง | ค่าที่ใช้ได้ | ตัวอย่าง |
|---|---|---|
| นาที | 0 ถึง 59 | 30 คือนาทีที่ 30 ของชั่วโมง |
| ชั่วโมง | 0 ถึง 23 | 9 คือ 09:00 ในระบบ 24 ชั่วโมง |
| วันที่ของเดือน | 1 ถึง 31 | 15 คือวันที่ 15 |
| เดือน | 1 ถึง 12 หรือ JAN ถึง DEC | 3 หรือ MAR คือเดือนมีนาคม |
| วันในสัปดาห์ | 0 ถึง 6 หรือ SUN ถึง SAT | 0 หรือ SUN คือวันอาทิตย์ 1 คือวันจันทร์ |
บางระบบยอมรับ 7 แทนวันอาทิตย์ แต่ไม่ใช่ทุกระบบ จึงควรใช้ 0 หรือ SUN รูปแบบนี้ของ cron ไม่มีช่องวินาที step ที่เล็กที่สุดจึงเป็นหนึ่งนาที
รายการ ช่วง step และชื่อ
หมายถึงทุกค่าในช่องนั้น* * * *รันทุกนาที- รายการ ใช้จุลภาคคั่น
0 9,17 * * *รันที่ 09:00 และ 17:00 ทุกวัน - ช่วง ใช้ขีดกลาง
1-5ในช่องวันในสัปดาห์หมายถึงวันจันทร์ถึงวันศุกร์ - step ใช้เครื่องหมายทับ
*/15ในช่องนาทีหมายถึงนาทีที่ 0, 15, 30 และ 4510-30/5หมายถึงนาทีที่ 10, 15, 20, 25 และ 30 - ชื่อ เช่น
MON-FRIใช้แทนตัวเลขได้ อ่านง่ายกว่า หาก scheduler ของคุณรองรับ
ส่วนเหล่านี้ใช้ร่วมกันได้ 0 8-18/2 * * * รันที่นาทีที่ 0 ของทุกชั่วโมงที่สอง ตั้งแต่ 08:00 ถึง 18:00
ตารางที่พบบ่อย
| Expression | ความหมาย |
|---|---|
* * * * * | ทุกนาที |
/15 * * * | ทุก 15 นาที |
0 * * * * | ที่นาทีที่ 0 ของทุกชั่วโมง |
0 2 * * * | ทุกวันเวลา 02:00 |
0 9 * * 1-5 | 09:00 ตั้งแต่วันจันทร์ถึงวันศุกร์ |
0 9,17 * * * | 09:00 และ 17:00 ทุกวัน |
30 6 1 * * | 06:30 ของวันที่ 1 ทุกเดือน |
0 0 * * 0 | เที่ยงคืนทุกวันอาทิตย์ |
0 0 1 1 * | เที่ยงคืนของวันที่ 1 มกราคม |
/5 9-17 * 1-5 | ทุก 5 นาที ตั้งแต่ 09:00 ถึง 17:55 ตั้งแต่วันจันทร์ถึงวันศุกร์ |
สังเกตว่า 0 0 * * คือเที่ยงคืน และ 0 12 * * คือเที่ยงวัน การใส่ชั่วโมงผิดเป็นหนึ่งในข้อผิดพลาดที่พบบ่อยที่สุด
วันที่ของเดือนและวันในสัปดาห์
เมื่อทั้งช่องวันที่ของเดือนและช่องวันในสัปดาห์ถูกกำหนดค่า งานจะรันเมื่ออย่างใดอย่างหนึ่งตรงกัน นี่คือกฎแบบดั้งเดิมของ Vixie cron และระบบจำนวนมากที่พัฒนาต่อจากมัน ดังนั้น 0 0 13 * 5 จะรันเที่ยงคืนของวันที่ 13 ทุกเดือน และรันทุกวันศุกร์ด้วย หลายคนคาดว่าจะรันเฉพาะวันศุกร์ที่ 13 เท่านั้น จึงได้จำนวนครั้งมากกว่าที่วางแผนไว้
หากช่องใดช่องหนึ่งในสองช่องเป็น * จะนับเฉพาะอีกช่องเท่านั้น หากต้องการรันเฉพาะวันศุกร์ที่ 13 ให้ตั้งงานทุกวันศุกร์ แล้วตรวจวันที่ในสคริปต์ scheduler อื่น รวมถึงบริการคลาวด์บางแห่ง อาจใช้กฎต่างออกไป จึงควรอ่านเอกสารของบริการนั้น
เขตเวลาและเวลาออมแสง
Cron รันตามนาฬิกาของเครื่องหรือบริการที่มันทำงานอยู่ ซึ่งปกติคือเขตเวลาท้องถิ่นของเครื่องนั้น งานที่ตั้งไว้ 02:30 จะรันที่ 02:30 ตามนาฬิกานั้น ตรวจเขตเวลาก่อน (บน Linux ใช้คำสั่ง date เพื่อดู) หากต้องการให้งานทุกตัวใช้นาฬิกาเดียวกันทุกที่ ทีมจำนวนมากตั้งเซิร์ฟเวอร์เป็น UTC และ scheduler บางตัวให้ตั้งเขตเวลาแยกสำหรับแต่ละงานได้
เวลาออมแสงเปลี่ยนนาฬิกาปีละสองครั้ง ในฤดูใบไม้ผลิ หลายพื้นที่จะข้ามจาก 02:00 ไปเป็น 03:00 ทันที งานที่ตั้งไว้ 02:30 จึงไม่มีเวลาให้รัน ในฤดูใบไม้ร่วง ชั่วโมงตั้งแต่ 01:00 ถึง 01:59 จะเกิดขึ้นสองครั้ง Scheduler แต่ละตัวจัดการกรณีเหล่านี้ต่างกัน บางตัวข้ามงาน บางตัวรันหนึ่งครั้ง และบางตัวรันสองครั้ง หากความแตกต่างนี้สำคัญ ให้หลีกเลี่ยงการตั้งงานในช่วงเวลาที่นาฬิกาเปลี่ยนตอนเช้าตรู่ หรือใช้ UTC
หกช่องและ Quartz
Scheduler บางตัวเพิ่มช่องวินาทีไว้ข้างหน้า เช่น /10 * * * * รันทุก 10 วินาที Quartz scheduler สำหรับ Java ใช้ลำดับวินาที นาที ชั่วโมง วันที่ของเดือน เดือน วันในสัปดาห์ และปีที่ไม่บังคับ และยังเพิ่มสัญลักษณ์พิเศษ 4 ตัว ดังนี้
?หมายถึง "ไม่กำหนดค่าเฉพาะ" Quartz กำหนดให้ใช้ในช่องวันที่ของเดือนหรือช่องวันในสัปดาห์ ช่องใดที่คุณไม่ได้ตั้งค่าLหมายถึงวันสุดท้ายLในช่องวันที่ของเดือนคือวันสุดท้ายของเดือน และ6Lในช่องวันในสัปดาห์คือวันศุกร์สุดท้ายWหมายถึงวันทำการที่ใกล้ที่สุด15Wคือวันทำการที่ใกล้วันที่ 15 ที่สุด และจะไม่ข้ามไปเดือนอื่น#หมายถึงวันในสัปดาห์ลำดับที่ n6#3คือวันศุกร์ที่สาม
Quartz นับวันต่างจากรูปแบบห้าช่อง โดย 1 คือวันอาทิตย์ และ 7 คือวันเสาร์ ดังนั้นวันจันทร์ถึงวันศุกร์จึงเป็น 2-6 ไม่ใช่ 1-5 ควรตรวจสอบรูปแบบที่ scheduler ของคุณใช้ก่อนคัดลอกบรรทัดใดๆ เสมอ
ข้อผิดพลาดที่พบบ่อย
*/7ในช่องนาที ค่าที่ได้คือ 0, 7, 14 ไปจนถึง 56 ค่าถัดไปจะเป็น 63 ซึ่งไม่มี ดังนั้นการรันหลัง 56 จะเป็นนาทีที่ 0 ของชั่วโมงถัดไป ช่วงห่างเพียงสี่นาที และระยะห่างไม่สม่ำเสมอ ควรใช้ step ที่หาร 60 ลงตัว เช่น 5, 10, 15 หรือ 30- วันที่ 30 กุมภาพันธ์ ไม่มีวันที่นี้อยู่จริง
0 0 30 2 *จึงไม่รันเลย ใช้หลักเดียวกันกับวันที่ 31 ในเดือนที่มี 30 วัน ภายใต้กฎ "อย่างใดอย่างหนึ่ง" การกำหนดวันในสัปดาห์ยังอาจทำให้งานรันในวันอื่นได้ จึงควรตรวจผลลัพธ์ - ชั่วโมง 24 หรือนาที 60 ค่าเหล่านี้อยู่นอกช่วง scheduler ส่วนใหญ่จะปฏิเสธตอนบันทึก แต่ไม่ใช่ทุกตัว
- คาดหวังวินาที บรรทัดห้าช่องจะรันเฉพาะที่นาทีเต็มเท่านั้น
- สับสน cron กับ regular expression ใน cron
หมายถึงทุกค่า ส่วนใน regular expressionหมายถึงการซ้ำรายการก่อนหน้า ใช้เครื่องมือทดสอบ regex สำหรับรูปแบบข้อความ และแยกบรรทัด cron ออกจากกัน
ตรวจเวลารันถัดไป
ก่อนพึ่งพาตารางงาน ให้อ่านบรรทัดเป็นภาษาธรรมดาและดูเวลารันถัดไปสองสามครั้งตัวอธิบาย cronทำได้ทั้งสองอย่าง และเป็นวิธีที่เร็วที่สุดในการจับกฎ "อย่างใดอย่างหนึ่ง" หรือ step ที่ผิดปกติ
คำตอบสั้นๆ
ช่องแรกคือนาทีหรือวินาที?
นาที ในรูปแบบห้าช่องมาตรฐาน มีเพียง scheduler หกช่องบางตัวเท่านั้นที่เพิ่มวินาที และจะวางไว้ข้างหน้า
ทำไมงานของฉันรันทุกวันศุกร์และวันที่ 13 ด้วย?
ช่องวันที่ของเดือนและช่องวันในสัปดาห์ถูกกำหนดค่าทั้งคู่ งานจึงรันเมื่อช่องใดช่องหนึ่งตรงกัน หากต้องการให้รันตามช่องเดียว ให้ตั้งอีกช่องเป็น *
Cron ใช้ UTC หรือไม่?
ใช่ ก็ต่อเมื่อเครื่องหรือบริการตั้งเป็น UTC ไม่เช่นนั้นจะใช้เขตเวลาท้องถิ่นของระบบนั้น
แปลจาก ฉบับภาษาอังกฤษ ด้วยความช่วยเหลือของ AI
ความคิดเห็น
ยังไม่มีความคิดเห็น มาเป็นคนแรกกันเลย


