เซิร์ฟเวอร์คุ้มค่าเพราะมันทำงานตอนที่คุณหลับ: สำรองข้อมูล หมุนเวียนล็อก ต่ออายุใบรับรอง รายงานตอนเก้าโมง Linux มีตัวตั้งเวลาสองแบบสำหรับเรื่องนี้ cron มีอายุสี่สิบปีและใช้แค่บรรทัดเดียว ตัวจับเวลาของ systemd ใช้ไฟล์เล็ก ๆ สองไฟล์ แต่แลกมาด้วยล็อก การรันชดเชยหลังเครื่องดับ และเวลาที่แม่นยำ คู่มือนี้อธิบายทั้งสองแบบบน Ubuntu 24.04 โดยตรวจทุกพฤติกรรมบนเซิร์ฟเวอร์ใหม่จากอิมเมจของเรา รวมถึงข้อผิดพลาดสามข้อที่ทำให้งาน cron ล้มเหลวโดยไม่มีข้อความใด ๆ
คุณต้องมีผู้ใช้ที่ใช้ sudo ได้ คู่มือตั้งค่า Ubuntu จะสร้างให้
1. cron ในห้านาที
cron ติดตั้งและทำงานอยู่บนอิมเมจ Ubuntu และ Debian ของเรา ผู้ใช้แต่ละคนมีตารางงานของตัวเอง แก้ไขของคุณด้วย:
crontab -e
แต่ละบรรทัดมีช่องเวลาห้าช่องและคำสั่งหนึ่งคำสั่ง:
# min hour day month weekday command
30 3 * * * /usr/local/bin/backup.sh >> /var/log/backup.log 2>&1
*/5 * * * * /usr/local/bin/check.sh
0 9 * * 1-5 /usr/local/bin/report.sh
@reboot /usr/local/bin/start-tunnel.sh
คือ: ทุกคืนเวลา 03:30 ทุก 5 นาที วันทำงานเวลา 09:00 และหนึ่งครั้งหลังบูตทุกครั้ง */5 หมายถึงทุกค่าที่ห้า 1-5 คือช่วง 1,15 คือรายการ ใช้เขตเวลาของเซิร์ฟเวอร์ ซึ่งเป็น UTC บนอิมเมจของเรา ตั้งของคุณครั้งเดียวด้วยคู่มือชื่อโฮสต์และเขตเวลา แล้ว cron จะใช้ตาม
ดูสิ่งที่รันไปแล้วด้วย journalctl -u cron ทุกการรันจะบันทึกผู้ใช้และคำสั่ง และกับดักทั้งสามก็ปรากฏตรงนั้น
กับดักที่ 1: ผลลัพธ์หายไป cron ส่งผลลัพธ์ของงานให้ผู้ใช้ทางอีเมล อิมเมจของเราไม่มีเมลเซิร์ฟเวอร์ journal จึงแสดง (CRON) info (No MTA installed, discarding output) และผลลัพธ์หายไป ให้เปลี่ยนเส้นทางเอง เหมือนตัวอย่างแรกที่ใช้ >> /var/log/backup.log 2>&1
กับดักที่ 2: เครื่องหมายเปอร์เซ็นต์ ใน crontab เครื่องหมาย % จะจบคำสั่งและเปลี่ยนส่วนที่เหลือเป็นอินพุตมาตรฐาน เราตั้งเวลา date +%F > /tmp/today และ journal แสดงสิ่งที่ cron รันจริงคือ CMD (date +) ไม่มีไฟล์ถูกเขียน และไม่มีข้อผิดพลาดใดมาถึงเรา ให้เขียน \% หรือใส่คำสั่งไว้ในสคริปต์แล้วตั้งเวลาสคริปต์นั้น
กับดักที่ 3: สภาพแวดล้อมต่างกัน cron รันงานด้วย /bin/sh ไม่ใช่ bash ในโฮมไดเรกทอรีของคุณ และด้วยสภาพแวดล้อมแบบน้อยที่สุด บน Ubuntu 24.04 PATH ดีกว่าชื่อเสียงของมัน: เป็นพาธระบบเต็ม รวม /usr/local/bin และ /snap/bin ทั้งสำหรับ root และผู้ใช้ทั่วไป สิ่งที่ยังขาดคือทุกอย่างใต้โฮมไดเรกทอรี: ~/.local/bin, node ของ nvm, pipx และ cargo ให้ใช้พาธเต็มในงาน หรือขึ้นต้นบรรทัดด้วย . $HOME/.profile;
งานที่เป็นของระบบไม่ใช่ของผู้ใช้ ให้วางใน /etc/cron.d/ เป็นไฟล์ที่มีช่องเพิ่มอีกหนึ่งช่อง คือผู้ใช้:
30 3 * * * root /usr/local/bin/backup.sh >> /var/log/backup.log 2>&1
Ubuntu ยังรันทุกอย่างใน /etc/cron.hourly, cron.daily, cron.weekly และ cron.monthly ที่นาทีที่ 17 ของทุกชั่วโมง เวลา 06:25 วันอาทิตย์เวลา 06:47 และวันที่ 1 ของเดือนเวลา 06:52 วางสคริปต์ที่รันได้ไว้ที่นั่น แล้วมันจะรันพร้อมกับตัวอื่น
2. ตัวจับเวลาของ systemd
ตัวจับเวลาประกอบด้วยสองยูนิต: เซอร์วิสที่ทำงาน และตัวจับเวลาที่บอกว่าเมื่อไร สร้างสคริปต์ก่อน แล้วจึงสร้างยูนิต
sudo nano /usr/local/bin/backup.sh
sudo chmod +x /usr/local/bin/backup.sh
sudo nano /etc/systemd/system/backup.service
[Unit]
Description=Nightly backup
[Service]
Type=oneshot
ExecStart=/usr/local/bin/backup.sh
sudo nano /etc/systemd/system/backup.timer
[Unit]
Description=Run the backup every night at 03:30
[Timer]
OnCalendar=*-*-* 03:30
Persistent=true
AccuracySec=1m
[Install]
WantedBy=timers.target
เปิดใช้งานตัวจับเวลา ไม่ใช่เซอร์วิส:
sudo systemctl daemon-reload
sudo systemctl enable --now backup.timer
systemctl list-timers backup.timer
list-timers แสดงรอบถัดไป เวลาที่เหลือ และรอบล่าสุด ล็อกไม่ต้องตั้งค่า: journalctl -u backup.service มีทุกการเริ่ม ทุกการจบ และทุกบรรทัดของผลลัพธ์พร้อมเวลา หากต้องการรันงานทันที ใช้ sudo systemctl start backup.service และนี่ก็เป็นวิธีทดสอบสคริปต์ก่อนเชื่อใจตารางเวลา
ไวยากรณ์ปฏิทิน OnCalendar อ่านว่า วันในสัปดาห์ ปี-เดือน-วัน ชั่วโมง:นาที:วินาที โดย * หมายถึงค่าใดก็ได้ ทดสอบนิพจน์ก่อนใช้:
systemd-analyze calendar "Mon..Fri *-*-* 03:00" --iterations 2
คำสั่งจะพิมพ์รูปแบบที่ปรับมาตรฐานแล้วและวันที่ถัดไป นิพจน์บางส่วนที่เราตรวจแล้ว:
| OnCalendar | ความหมาย |
|---|---|
*-*-* 03:30 | ทุกวันเวลา 03:30 |
Mon..Fri *-*-* 09:00 | วันทำงานเวลา 09:00 |
*:0/15 | ทุก 15 นาที |
weekly | วันจันทร์เวลา 00:00 |
*-*-01 04:00 | วันที่ 1 ของทุกเดือนเวลา 04:00 |
*-*-* 03:00 Europe/Kyiv | 03:00 ตามเวลาเคียฟ ในการทดสอบของเราทำงานเวลา 01:00 UTC |
การตั้งค่าสามอย่างที่ควรรู้ Persistent=true บันทึกรอบล่าสุดลงดิสก์ และรันชดเชยรอบที่พลาดไปขณะเซิร์ฟเวอร์ปิดหรือตัวจับเวลาหยุดอยู่ เราหยุดตัวจับเวลาทุกสองนาทีของเรา รอให้รอบที่กำหนดผ่านไป แล้วเปิดใหม่: รอบที่พลาดเริ่มทำงานในวินาทีเดียวกันนั้น หากไม่มี Persistent มันจะแค่รอรอบถัดไป
เรื่องไม่คาดคิดคือ AccuracySec โดยค่าเริ่มต้น systemd รวมตัวจับเวลาไว้ในหน้าต่างหนึ่งนาทีเพื่อลดการปลุกระบบ รอบแรกของเราจึงมาตอน 07:42:18 ไม่ใช่ 07:42:00 เมื่อตั้ง AccuracySec=1s รอบต่อมาตรงวินาทีพอดีที่ 07:46:00 และ 07:48:00 ตั้งค่านี้เมื่อนาทีสำคัญ ส่วนการสำรองข้อมูลตอนกลางคืนใช้ค่าเริ่มต้นได้
RandomizedDelaySec=10m ตั้งใจทำตรงกันข้าม: กระจายเวลาเริ่มไปในหน้าต่างหนึ่ง เพื่อไม่ให้เซิร์ฟเวอร์สิบเครื่องเข้าถึงที่เก็บสำรองข้อมูลเดียวกันในวินาทีเดียวกัน
สำหรับงานที่รันครั้งเดียว ไม่ต้องใช้ไฟล์เลย:
sudo systemd-run --on-active=30m --unit=cleanup-once /usr/local/bin/cleanup.sh
คำสั่งนี้สร้างตัวจับเวลาชั่วคราวที่ทำงานครั้งเดียวแล้วหายไป จนถึงตอนนั้น systemctl list-timers จะแสดงมันไว้
3. ควรใช้แบบไหน
| cron | ตัวจับเวลา systemd | |
|---|---|---|
| การตั้งค่า | 1 บรรทัด | 2 ไฟล์ |
| ล็อก | เฉพาะเมื่อเปลี่ยนเส้นทางผลลัพธ์ | journalctl -u name.service |
| รอบที่พลาดขณะเซิร์ฟเวอร์ปิด | หายไป | รันตอนบูตด้วย Persistent=true |
| งานยังรันอยู่เมื่อถึงรอบถัดไป | เริ่มสำเนาที่สอง | ข้ามไปจนกว่าตัวแรกจะเสร็จ |
| เวลาที่แม่นยำ | ระดับนาที | ระดับวินาทีด้วย AccuracySec=1s |
| สถานะ | ไม่มี | list-timers และ systemctl status |
ใช้ cron กับบรรทัดสั้น ๆ ที่อีกปีหนึ่งคุณยังจำได้ ใช้ตัวจับเวลากับทุกงานที่คุณต้องเห็นเมื่อมันล้มเหลว งานที่ห้ามซ้อนกัน หรืองานที่ต้องรันแม้จะพลาดไปเพราะรีสตาร์ต: การสำรองข้อมูล การต่ออายุใบรับรอง การล้างฐานข้อมูล ถ้างาน cron อาจซ้อนกัน ให้ครอบไว้ด้วย flock -n /tmp/backup.lock /usr/local/bin/backup.sh แล้วสำเนาที่สองจะออกทันที
ตัวตั้งเวลาทั้งสองแบบรันงานแล้วก็หยุด โปรแกรมที่ต้องทำงานตลอดเวลาและกลับมาเองหลังแครช ต้องใช้เซอร์วิส ไม่ใช่ตารางเวลา ดูวิธีสร้างเซอร์วิส systemd และสำหรับ Windows ดูวิธีรันสคริปต์ 24/7 บน Windows Server ตัวจับเวลาตัวแรกที่ดีคือตัวจากคู่มือสำรองข้อมูลด้วย restic ของเรา ส่วนการอัปเดตความปลอดภัยอัตโนมัติ เป็นตัวจับเวลาที่ Ubuntu มีมาให้แล้ว คือ apt-daily-upgrade.timer หนึ่งใน 17 ตัวที่ทำงานบนเซิร์ฟเวอร์ใหม่
ความคิดเห็น
ยังไม่มีความคิดเห็น เป็นคนแรกสิ