Quick Start: Chạy task đầu tiên trong 5 phút
Cần triển khai nhanh? Đây là cách tạo một script tự động ghi log mỗi phút để bạn thấy ngay sức mạnh của systemd.
Bước 1: Chuẩn bị script
# Tạo thư mục quản lý script
sudo mkdir -p /opt/scripts
# Tạo file script đơn giản
sudo bash -c 'cat <<EOF > /opt/scripts/hello-timer.sh
#!/bin/bash
echo "Task thực thi lúc: \$(date)"
EOF'
# Cấp quyền chạy
sudo chmod +x /opt/scripts/hello-timer.sh
Bước 2: Định nghĩa Service
File này mô tả công việc cụ thể. Hãy tạo file tại /etc/systemd/system/hello-timer.service:
[Unit]
Description=Script ghi log định kỳ
[Service]
Type=oneshot
ExecStart=/opt/scripts/hello-timer.sh
Bước 3: Thiết lập Timer
File này đóng vai trò bộ đếm giờ. Tạo file /etc/systemd/system/hello-timer.timer (tên phải khớp với file service):
[Unit]
Description=Chạy hello-timer mỗi phút
[Timer]
OnCalendar=*:*:00
Unit=hello-timer.service
[Install]
WantedBy=timers.target
Kích hoạt để hệ thống bắt đầu làm việc:
sudo systemctl daemon-reload
sudo systemctl enable --now hello-timer.timer
Để kiểm tra, bạn dùng lệnh: journalctl -u hello-timer.service. Log sẽ xuất hiện đều đặn mỗi phút.
Tại sao mình bỏ Cron để sang systemd Timer?
Crontab rất tiện cho các tác vụ cá nhân nhỏ lẻ. Tuy nhiên, khi quản lý cụm server Ubuntu 22.04 chạy 4GB RAM với hàng chục job backup đồng thời, Cron khiến mình mất kiểm soát.
Vấn đề lớn nhất là Logging. Với Cron, script lỗi thường im lặng biến mất. Bạn phải tự dẫn hướng log bằng >> /var/log/app.log 2>&1 rất thủ công. Với systemd, mọi thứ được đẩy thẳng vào journald. Bạn chỉ cần một lệnh duy nhất để xem toàn bộ lịch sử chạy và vết lỗi.
Tiếp theo là khả năng ràng buộc (Dependency). Bạn muốn script chỉ chạy sau khi MySQL đã khởi động hoặc mạng đã thông? Cron không thể làm điều này một cách tự nhiên. Systemd thì khác, nó quản lý mối quan hệ giữa các dịch vụ cực kỳ chặt chẽ.
Đặc biệt là giới hạn tài nguyên. Mình từng gặp cảnh script backup ngốn sạch 100% CPU khiến web server sập. Với systemd, mình giới hạn ngay MemoryLimit=500M và CPUQuota=30% trong file service để bảo vệ hệ thống.
Hiểu sâu cấu trúc systemd Timer
Bí quyết nằm ở sự tách biệt giữa Service (làm cái gì) và Timer (khi nào làm).
1. File Service (.service)
Tập trung vào cách thực thi script:
Type=oneshot: Phù hợp cho các job chạy xong rồi nghỉ như dọn dẹp log hoặc backup database.User=www-data: Chạy script dưới quyền user cụ thể thay vì root để giảm rủi ro bảo mật.
2. File Timer (.timer)
Nơi cấu hình thời gian linh hoạt:
- Monotonic timers: Tính thời gian từ lúc boot hoặc từ lần chạy trước. Ví dụ:
OnUnitActiveSec=1h(cứ cách 1 tiếng chạy lại). - Realtime timers (OnCalendar): Chạy theo lịch như Cron nhưng dễ đọc hơn.
Một vài ví dụ OnCalendar phổ biến:
*-*-* 03:00:00: Đúng 3 giờ sáng mỗi ngày.Mon *-*-* 00:00:00: Nửa đêm thứ Hai hàng tuần.*:0/20: Tần suất 20 phút một lần.
Xử lý lỗi thông minh với Retry tự động
Đây là tính năng “đáng đồng tiền bát gạo”. Nếu script đồng bộ dữ liệu lên Cloud thất bại do mạng chập chờn, systemd sẽ tự thử lại cho bạn.
Cấu hình thêm vào file .service:
[Service]
ExecStart=/opt/scripts/sync-cloud.sh
Restart=on-failure
RestartSec=60s
StartLimitBurst=5
Cấu hình này yêu cầu: Nếu lỗi, đợi 60 giây rồi thử lại. Sau 5 lần thất bại liên tiếp mới thực sự dừng lại và gửi cảnh báo.
Các lệnh quản lý “bỏ túi”
Để kiểm soát các timer đang chạy, mình thường dùng 3 lệnh sau:
systemctl list-timers: Xem danh sách job, biết chính xác khi nào job tiếp theo sẽ chạy.systemctl status task.timer: Kiểm tra trạng thái bộ đếm giờ.journalctl -u task.service -f: Theo dõi log trực tiếp (real-time) để debug nhanh.
Kinh nghiệm thực tế để tránh “ăn hành”
Sau nhiều lần troubleshoot trên môi trường production, đây là 3 lưu ý quan trọng:
- Dùng đường dẫn tuyệt đối: Systemd không biết
python3nằm ở đâu. Hãy viết/usr/bin/python3 /path/to/script.py. - Tận dụng tính năng Persistent: Nếu server tắt lúc 2h sáng (giờ chạy backup), khi bật lại lúc 7h, timer có
Persistent=truesẽ chạy bù ngay lập tức. Cron mặc định sẽ bỏ qua luôn job đó. - Đặt tên file khớp nhau: Luôn đặt tên
app-sync.servicevàapp-sync.timergiống nhau để quản lý dễ dàng và hệ thống tự hiểu liên kết.
Dù việc tạo 2 file có vẻ rườm rà hơn 1 dòng Crontab, nhưng sự minh bạch và khả năng kiểm soát tài nguyên mà systemd Timer mang lại là hoàn toàn xứng đáng.

