Lập lịch job automation dài hơi bằng systemd timer

Bạn quản lý một VPS chạy automation, giám sát hệ thống, backup cơ sở dữ liệu, đồng bộ file, kiểm tra chứng chỉ SSL định kỳ. Sử dụng cron đến một lúc nào đó khiến bạn đau đầu: job chạy quá lâu bị đè lên nhau, không biết job nào fail, không kiểm soát được tài nguồn mỗi tiến trình. Đã đến lúc chuyển sang systemd timer, công cụ lập lịch job automation dài hơi được tích hợp sẵn trên mọi bản phân phối Linux hiện đại.
Vì sao nên dùng systemd timer thay cron?
Cron là công cụ tuyệt vời cho các tác vụ đơn giản và chạy nhanh. Nhưng với job automation dài hơi, một script chạy cả chục phút để xử lý log, đồng bộ database, hoặc chạy AI agent, cron bộc lộ điểm yếu: không có cơ chế restart khi lỗi, không giới hạn RAM/CPU, không log lỗi mặc định, và dễ gây chồng lấn khi job trước chưa kết thúc.
Systemd timer giải quyết từng vấn đề đó. Một job trong systemd sẽ:
- Tự động restart nếu lệnh trả về exit code khác 0 (Restart=on-failure)
- Giới hạn CPU, RAM, tiến trình con bằng cgroup (CPUQuota, MemoryMax)
- Ghi log ra journald, đọc lỗi bằng
journalctl -u name.service - Ngăn chồng lấn bằng cơ chế khóa (Unit/Conflicts)
- Điều khiển thời gian chạy với cú pháp Calendar linh hoạt hơn crontab
Đây là lý do các môi trường production ưu tiên systemd timer cho mọi tác vụ quan trọng thay vì cron.
| Tiêu chí | Cron | Systemd timer |
|---|---|---|
| Restart khi lỗi | Không tự động | Tự động theo cấu hình Restart= |
| Giới hạn tài nguyên | Không | Cgroup (CPU, RAM, IO) |
| Log lỗi | Ghi vào syslog, khó đọc | journald, dùng journalctl lọc |
| Chồng lấn job | Không kiểm soát | Chặn bằng Conflicts/Before/After |
| Quản lý dependency | Không | Sau network.target, database.service... |
Yêu cầu trước khi bắt đầu
- Một VPS chạy Linux với systemd (Ubuntu 24.04, Debian 12, AlmaLinux 9, tất cả đều dùng systemd)
- Quyền root hoặc sudo
- Hiểu biết cơ bản về Bash script và đường dẫn file
- Bạn cần một script thực thi đã có sẵn, ví dụ
/usr/local/bin/backup.sh
Bước 1, Tạo unit service cho script
Mỗi job automation cần một systemd service để định nghĩa lệnh chạy và chính sách restart. Tạo file /etc/systemd/system/backup-task.service:
[Unit]
Description=Backup database và upload lên S3
After=network-online.target
Wants=network-online.target
[Service]
Type=simple
ExecStart=/usr/local/bin/backup.sh
Restart=on-failure
RestartSec=10s
StandardOutput=journal
StandardError=journal
User=root
[Install]
WantedBy=multi-user.target
Giải thích:
ExecStart, đường dẫn rất cao tới script hoặc lệnh cần chạy.Restart=on-failure, tự động restart nếu script trả về mã lỗi khác 0 hoặc bị kill bởi signal (không phải SIGTERM).RestartSec=10s, chờ 10 giây trước khi restart, tránh vòng lặp crash nhanh.StandardOutput=journalvàStandardError=journal, ghi log vào journald để dễ tra cứu.User=root, script chạy với quyền root. Bạn có thể chọn user khác nếu cần.
Verify service: Sau khi tạo file, chạy systemctl daemon-reload rồi kiểm tra cú pháp bằng systemctl cat backup-task.service.
Bước 2, Tạo timer để lập lịch
File timer cùng tên nhưng đuôi .timer, đặt trong /etc/systemd/system/backup-task.timer:
[Unit]
Description=Chạy backup-task mỗi ngày lúc 3 giờ sáng
Requires=backup-task.service
[Timer]
OnCalendar=*-*-* 03:00:00
Unit=backup-task.service
Persistent=true
[Install]
WantedBy=timers.target
Giải thích:
OnCalendar=*-*-* 03:00:00, chạy mỗi ngày lúc 3h sáng. Cú pháp này tương tự crontab nhưng đọc dễ hơn: tháng-ngày-giờ:phút:giây. Có thể viếtMon..Fri 09:00:00cho ngày trong tuần, hoặc*-*-1..7 03:00:00cho 7 ngày đầu tháng.Persistent=true, nếu server tắt vào 3h và bật lại lúc 5h, timer sẽ kích hoạt ngay khi khởi động thay vì bỏ lỡ job. Đây là tính năng cron không có.Requires, đảm bảo timer kích hoạt service chứ không chạy lung tung.
Verify timer: Chạy systemctl enable --now backup-task.timer, kiểm tra trạng thái bằng systemctl list-timers --all. Output sẽ hiển thị dòng chứa backup-task.timer và lần chạy kế tiếp.
Bước 3, Giới hạn tài nguyên bằng cgroup
Điểm mạnh lớn nhất của systemd timer so với cron là khả năng kiểm soát CPU và RAM mỗi job thông qua cgroup. Thêm các directive sau vào section [Service] trong file backup-task.service:
[Service]
# Giới hạn CPU: tối đa 50% một core
CPUQuota=50%
# Giới hạn RAM: tối đa 512 MB
MemoryMax=512M
MemoryHigh=400M
# Giới hạn IO đọc/ghi
IOReadBandwidthMax=/dev/sda 100M
IOWriteBandwidthMax=/dev/sda 50M
Tác dụng:
CPUQuota=50%, job chỉ được dùng tối đa nửa core CPU. Trên VPS có 2 vCPU, job này không thể đốt hết tài nguyên của server.MemoryMax=512M, giới hạn cứng. Nếu job vượt 512 MB, systemd sẽ kill tiến trình (OOM kill).MemoryHigh=400M, giới hạn mềm. Job vượt ngưỡng này sẽ bị chậm lại (throttle), tránh kill đột ngột nhưng vẫn đảm bảo không chiếm hết RAM.IOReadBandwidthMaxvàIOWriteBandwidthMax, giới hạn bandwidth đọc/ghi cho ổ đĩa. Hữu ích khi server có nhiều job I/O khác cùng chạy.
Verify: Sau khi reload và restart service, dùng systemd-cgls hoặc cat /sys/fs/cgroup/system.slice/backup-task.service/memory.max để kiểm tra giới hạn có hiệu lực.
Với job automation dài hơi, ví dụ chạy OpenClaw crawl dữ liệu trong nhiều giờ, giới hạn RAM là bắt buộc để VPS không shutdown vì OOM. Bạn có thể cấu hình MemoryMax=1G hoặc CPUQuota=30% tùy nhu cầu.
Bước 4, So sánh cú pháp lịch: cron vs systemd calendar
Bảng dưới đây giúp bạn chuyển đổi nhanh từ cron sang systemd. Các bạn từng dùng cron trên VPS Linux sẽ thấy cú pháp systemd dễ đọc hơn nhiều:
| Tác vụ | Crontab | systemd OnCalendar |
|---|---|---|
| Mỗi ngày lúc 2h30 | 30 2 * * * | *-*-* 02:30:00 |
| Mỗi 15 phút | */15 * * * * | *-*-* *:0/15:00 |
| Mỗi thứ 3 lúc 9h | 0 9 * * 2 | Tue *-*-* 09:00:00 |
| Mùng 1 mỗi tháng lúc 0h | 0 0 1 * * | *-*-1 00:00:00 |
| Mỗi 2 giờ trong giờ làm việc | 0 8-18/2 * * 1-5 | Mon..Fri *-*-* 08:00/2:00 |
Lưu ý: systemd timer có thể chạy với độ chính xác đến giây (.timer cho phép cấu hình AccuracySec=1us mặc định là 1 phút). Cron chỉ đạt độ chính xác phút.
Xử lý lỗi thường gặp
1. Timer không kích hoạt service
Kiểm tra bằng systemctl status backup-task.timer. Nếu thấy Active: inactive (dead), bạn quên enable timer. Chạy systemctl enable --now backup-task.timer.
2. Job chạy liên tục (restart loop)
Nguyên nhân: script exit code khác 0 liên tục. Xem log bằng journalctl -u backup-task.service -n 50 --no-pager để đọc lỗi. Thêm StartLimitIntervalSec=300 và StartLimitBurst=3 vào [Unit] để giới hạn số lần restart, sau 3 lần trong 5 phút, systemd ngừng thử.
3. Job chạy sai thời gian
Kiểm tra cú pháp calendar bằng lệnh systemd-analyze calendar "*-*-* 03:00:00". Lệnh này sẽ parse và hiển thị lần chạy kế tiếp, giúp bạn debug lịch dễ dàng.
Câu hỏi thường gặp
Có nên xóa cron hoàn toàn khi chuyển sang systemd timer không?
Không bắt buộc. Bạn có thể giữ cron cho các tác vụ cực kỳ đơn giản (xóa cache mỗi giờ). Nhưng với job automation dài hơi cần kiểm soát tài nguyên, như giám sát log, backup, crawl, training mô hình nhỏ, hãy dùng systemd timer. Cả hai có thể chạy song song.
Làm sao để chạy timer ngay lập tức thay vì đợi lịch?
Dùng systemctl start backup-task.service để chạy thủ công. Timer không can thiệp, service chạy độc lập. Sau đó timer vẫn hoạt động bình thường theo lịch.
Systemd timer có chạy trên mọi VPS không?
Hầu hết. Từ Ubuntu, Debian, AlmaLinux, Rocky Linux cho đến CentOS Stream, tất cả đều dùng systemd. Nếu bạn thuê VPS Windows thì Windows có Task Scheduler riêng. Tuy nhiên, với Linux server, systemd timer là tiêu chuẩn mặc định.
Làm sao để kiểm tra timer đang chạy đúng không?
Dùng systemctl list-timers --all xem danh sách. Dùng journalctl -u backup-task.service đọc log chi tiết từng lần chạy. Nếu có lỗi, log sẽ ghi rõ mã thoát.
Giới hạn cgroup có ảnh hưởng đến hiệu năng không?
Không đáng kể. Cgroup là cơ chế nhân Linux, chi phí rất thấp. Bạn nên đặt giới hạn RAM/CPU cho mọi job automation dài hơi, đặc biệt trên VPS có RAM hạn chế, để tránh tiến trình rogue đốt hết tài nguyên. Một thuê VPS giá rẻ 2 GB RAM vẫn ổn nếu mỗi job được cấu hình đúng.
Có thể dùng timer cho job chạy dưới user thường không?
Có. Dùng systemctl --user với linger. Tạo service + timer trong ~/.config/systemd/user/. Cơ chế restart và cgroup vẫn hoạt động. Hữu ích cho VPS có nhiều user chạy automation riêng.
Bài viết liên quan
- 10 workflow n8n hữu ích webmaster nên biết và tự host
- Những workflow nên có cho sysadmin trên VPS
- Gửi cảnh báo hệ thống VPS qua Telegram bot bằng script Bash
- Dùng rclone backup VPS lên Google Drive


