AI Automation

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íCronSystemd timer
Restart khi lỗiKhông tự độngTự động theo cấu hình Restart=
Giới hạn tài nguyênKhôngCgroup (CPU, RAM, IO)
Log lỗiGhi vào syslog, khó đọcjournald, dùng journalctl lọc
Chồng lấn jobKhông kiểm soátChặn bằng Conflicts/Before/After
Quản lý dependencyKhôngSau 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=journalStandardError=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ết Mon..Fri 09:00:00 cho ngày trong tuần, hoặc *-*-1..7 03:00:00 cho 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.
  • IOReadBandwidthMaxIOWriteBandwidthMax, 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ụCrontabsystemd OnCalendar
Mỗi ngày lúc 2h3030 2 * * **-*-* 02:30:00
Mỗi 15 phút*/15 * * * **-*-* *:0/15:00
Mỗi thứ 3 lúc 9h0 9 * * 2Tue *-*-* 09:00:00
Mùng 1 mỗi tháng lúc 0h0 0 1 * **-*-1 00:00:00
Mỗi 2 giờ trong giờ làm việc0 8-18/2 * * 1-5Mon..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=300StartLimitBurst=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

Lưu ý: Bài viết mang tính tham khảo, tổng hợp kiến thức chung. Mỗi hệ thống, hạ tầng và nhu cầu có đặc thù riêng, nên kiểm thử trong môi trường an toàn và tham vấn kỹ sư trước khi triển khai thực tế.