Hướng dẫn tạo Systemd Service và Systemd Timer trên CentOS Stream 9: Thay thế Crontab chuẩn Enterprise

CentOS tutorial - IT technology blog
CentOS tutorial - IT technology blog

2 giờ sáng, database backup chết lặng và bài học đắt giá với Crontab

Đúng 2h15 sáng, màn hình điện thoại rung bần bật vì alert từ hệ thống monitoring. Phân vùng /backup chạm ngưỡng 98% dung lượng. Tiến trình đồng bộ dữ liệu sang NAS lưu trữ 4TB bị treo cứng ngắc suốt 4 tiếng mà không xuất hiện lấy một dòng log lỗi.

Mình SSH vội vào cụm CentOS Stream 9 production, gõ crontab -l thì lịch sao lưu vẫn nằm đó, cú pháp 5 dấu sao chuẩn xác. Mở /var/log/cron, hệ thống chỉ ghi nhận đúng một dòng thông báo: job đã kích hoạt lúc 22:00. Hết. Không manh mối, không exit code, không biết script Python tắt lịm ở bước nào.

Điểm yếu chí mạng của cron nằm ở cơ chế “bắn rồi quên” (fire-and-forget). Cron đẩy tiến trình chạy ngầm rồi buông tay. Khi script rò rỉ bộ nhớ ngốn sạch 8GB RAM khiến Linux OOM Killer thẳng tay trảm tiến trình, cron hoàn toàn câm lặng. Bạn phải mò mẫm qua cả chục file log rải rác để đoán nguyên nhân. Trải nghiệm đau thương đó khiến team mình quyết định: khai tử hoàn toàn crontab trên toàn bộ hạ tầng mới. Thay vào đó, chúng mình chuyển sang dùng cặp bài trùng systemd service và systemd timer.

Khái niệm cốt lõi: Tại sao Systemd Timer vượt trội hơn Crontab?

Khác với một dòng lệnh đơn độc trong crontab, systemd tách bài toán tự động hóa thành hai phần độc lập:

  • Service Unit (.service): Quy định tác vụ chạy cái gì. Mục này định rõ đường dẫn script, quyền user thực thi, biến môi trường và hạn ngạch CPU/RAM.
  • Timer Unit (.timer): Quy định thời điểm kích hoạt. Bạn có thể hẹn giờ theo lịch cố định, lặp lại sau mỗi chu kỳ, hoặc kích hoạt sau khi OS khởi động xong 5 phút.

Kiến trúc module này mang lại những ưu thế vượt bậc khi vận hành thực tế:

  • Gom log tập trung về journalctl: Toàn bộ luồng stdout lẫn stderr tự động đổ về systemd journal. Bạn trace vết lỗi theo từng mili-giây mà không cần cấu hình rườm rà dạng >> /var/log/app.log 2>&1.
  • Kiểm soát tài nguyên chặt chẽ: Bạn dễ dàng siết trần tài nguyên bằng Cgroups, ví dụ giới hạn script chỉ được ăn tối đa 512MB RAM và 50% của 1 core CPU, bảo vệ an toàn cho ứng dụng chính.
  • Bắt kịp tác vụ bị lỡ (Catch-up): Server bảo trì reboot đúng khung giờ backup? Tùy chọn Persistent=true sẽ kích hoạt chạy bù ngay khi OS vừa load xong.
  • Rải tải ngẫu nhiên: Tham số RandomizedDelaySec giúp phân tán thời điểm chạy của hàng trăm server, tránh hiện tượng nghẽn I/O đồng loạt.

Thực hành chi tiết: Thiết lập Systemd Service & Timer trên CentOS Stream 9

Chúng ta cùng xử lý một kịch bản thực tế: Viết script tự động nén dọn log tạm cũ hơn 7 ngày, đóng gói vào service và kích hoạt định kỳ lúc 02:00 sáng mỗi ngày.

Bước 1: Chuẩn bị file script thực thi

Tạo thư mục chuẩn để chứa các script vận hành của hệ thống:

sudo mkdir -p /opt/ops-scripts
sudo nano /opt/ops-scripts/cleanup-backup.sh

Soạn nội dung script:

#!/bin/bash
set -euo pipefail

NOW=$(date '+%Y-%m-%d %H:%M:%S')
echo "[$NOW] INFO: Bat dau kiem tra va don dep log..."

# Tim va xoa cac file log cu hon 7 ngay trong thu muc temp
DELETED_COUNT=$(find /tmp -type f -name "*.log" -mtime +7 -print -delete | wc -l)

echo "[$NOW] SUCCESS: Da don dep tong cong $DELETED_COUNT file log."

Cấp quyền thực thi và khóa quyền truy cập chỉ cho root:

sudo chmod 750 /opt/ops-scripts/cleanup-backup.sh
sudo chown root:root /opt/ops-scripts/cleanup-backup.sh

Bước 2: Tạo Systemd Service Unit

Tạo file unit mới bên trong /etc/systemd/system/:

sudo nano /etc/systemd/system/cleanup-backup.service

Thiết lập nội dung service:

[Unit]
Description=Don dep backup va log cu he thong
After=network.target local-fs.target

[Service]
Type=oneshot
User=root
ExecStart=/opt/ops-scripts/cleanup-backup.sh
MemoryMax=512M
CPUQuota=50%

Lưu ý kỹ thuật: Với các batch job chạy một lần rồi thoát, bạn bắt buộc đặt Type=oneshot. Không dùng directive Restart=on-failure cho Type=oneshot độc lập vì systemd sẽ từ chối khởi chạy; quyền điều phối lịch chạy lúc này hoàn toàn do Timer quản lý.

Bước 3: Tạo Systemd Timer Unit

Tạo file timer có tên trùng khớp với file service để systemd tự động liên kết:

sudo nano /etc/systemd/system/cleanup-backup.timer

Khai báo cấu hình timer:

[Unit]
Description=Timer kich hoat cleanup-backup.service luc 2h sang

[Timer]
OnCalendar=*-*-* 02:00:00
Persistent=true
RandomizedDelaySec=10m
Unit=cleanup-backup.service

[Install]
WantedBy=timers.target

Giải mã các tham số quan trọng:

  • OnCalendar=*-*-* 02:00:00: Thời điểm kích hoạt lúc 02:00 mỗi ngày.
  • Persistent=true: Đánh dấu thời điểm chạy cuối cùng vào disk. Nếu máy chủ offline lúc 02:00, job sẽ tự chạy bù ngay sau khi server khởi động lại.
  • RandomizedDelaySec=10m: Tạo độ trễ ngẫu nhiên từ 0 đến 10 phút, san đều tải I/O đĩa cứng.

Bước 4: Nạp cấu hình và kích hoạt Timer

Yêu cầu systemd quét lại các unit file mới:

sudo systemctl daemon-reload

Bật và chạy timer ngay lập tức (bạn chỉ kích hoạt timer, không enable service):

sudo systemctl enable --now cleanup-backup.timer

Kiểm tra trạng thái hàng đợi trên CentOS Stream 9:

systemctl list-timers --all | grep cleanup-backup

Đầu ra hiển thị trực quan thời gian chạy kế tiếp và thời gian đếm ngược còn lại:

NEXT                         LEFT          LAST PASSED UNIT                  ACTIVATES
Fri 2026-11-06 02:07:14 UTC  13h left      n/a  n/a    cleanup-backup.timer  cleanup-backup.service

Bước 5: Kiểm tra và gỡ lỗi nhanh

Bạn không cần chỉnh đồng hồ hệ thống hay thức tới 2h sáng để test. Hãy gọi trực tiếp service để kiểm chứng logic:

sudo systemctl start cleanup-backup.service

Kiểm tra mã trạng thái trả về:

systemctl status cleanup-backup.service

Đọc toàn bộ log thực thi chuẩn chỉ bằng journalctl:

sudo journalctl -u cleanup-backup.service -e --no-pager

Theo dõi luồng log trực tiếp (real-time tailing) tương tự tail -f:

sudo journalctl -u cleanup-backup.service -f

Lời kết

Viết systemd timer tốn công hơn crontab: bạn phải tạo 2 file thay vì gõ vội 1 dòng lệnh. Nhưng cái giá đó quá rẻ. Đổi lại, bạn nắm trong tay hệ thống log tập trung qua journalctl, khả năng kẹp trần RAM/CPU và cơ chế chạy bù tin cậy. Khi hạ tầng scale lên vài chục máy chủ CentOS Stream 9, sự ổn định này chính là thứ giữ cho hệ thống vững vàng và giúp bạn ngủ ngon mỗi đêm.

Share: