Làm thế nào (và tại sao) để thay thế công việc cron bằng bộ tính giờ systemd

Tác giả sysadmin, T.Chín 06, 2023, 09:05:30 SÁNG

« Chủ đề trước - Chủ đề tiếp »

0 Thành viên và 1 Khách đang xem chủ đề.

Làm thế nào (và tại sao) để thay thế công việc cron bằng bộ tính giờ systemd


Một trong những thay đổi mà systemd mang lại là một cách mới để lên lịch công việc, tinh tế hơn cron. Một số bản phân phối Linux không còn gửi cron nữa. Đã đến lúc kiểm tra bộ tính giờ systemd.


1. Tại sao bộ định thời systemd lại thay thế cron

Nguồn gốc của cron có từ năm 1975, trong Phiên bản 7 Unix. Độ tin cậy của nó đã sớm khiến nó trở thành một công cụ được yêu thích để lập lịch các tác vụ chạy vào những ngày và giờ cụ thể. Phải thừa nhận rằng cú pháp của nó khá kỳ quặc. Nếu không sử dụng nó thường xuyên, có thể bạn sẽ cần phải tra cứu những điểm tốt hơn mỗi khi muốn sắp xếp công việc.

Trong lịch trình cron, ngày và tháng được đánh số bắt đầu từ một. Tuy nhiên, các ngày trong tuần được đánh số từ 0 đến 6, từ Chủ Nhật đến Thứ Bảy. Và trên một số hệ thống, bảy cũng có nghĩa là Chủ Nhật. Tuy nhiên, dù kỳ quặc như thế này, nó vẫn có tác dụng.

Trình quản lý dịch vụ systemd mang lại nhiều điều hơn là một sự thay thế đơn giản cho trình quản lý khởi động init. Một phần của những gì nó mang lại là sự thay thế hiện đại cho cron, dưới dạng bộ tính giờ systemd. Những thứ này mang lại sự linh hoạt hơn cron và không cần tiện ích bên ngoài khác. Chúng được tích hợp ngay vào tất cả các bản phân phối systemd.

Điều đó có nghĩa là bộ hẹn giờ hoạt động theo cùng một cách trên tất cả các cài đặt systemd. Có nhiều phiên bản thay thế cron và cron-like. Nếu bạn cần tiêu chuẩn hóa trên một số máy tính, systemd sẽ giúp cuộc sống của bạn dễ dàng hơn. Các bộ tính giờ giống nhau sẽ chạy theo cùng một cách trên tất cả chúng. Trên thực tế, một số bản phân phối dựa trên systemd không còn gửi cron như một phần của sản phẩm tiêu chuẩn của họ nữa.

Không có gì ngạc nhiên khi các bản phân phối có nguồn gốc từ Red Hat bao gồm Fedora không gửi cron, vì systemd là một sáng kiến của Red Hat. Arch và các công cụ phái sinh của nó không bao gồm cron, nhưng điều đó có lẽ liên quan nhiều hơn đến việc chúng cung cấp mức phân phối tối thiểu đến mức bạn có thể điền các ứng dụng phù hợp. Các bản phân phối khác, chẳng hạn như Solus, cũng không thấy cần phải có cron. Tất nhiên, bạn có thể cài đặt cron trên bất kỳ bản phân phối nào bạn thích, nhưng không có lý do thuyết phục nào để làm như vậy.

2. Bộ hẹn giờ systemd hoạt động như thế nào

Với bộ tính giờ systemd, bạn cần tạo hai tệp. Một là một tập tin dịch vụ. Khi dịch vụ chạy, nó sẽ khởi chạy quy trình cho bạn. Vì vậy, tệp dịch vụ cần biết về quy trình mục tiêu của bạn.

Tệp thứ hai bạn cần tạo là tệp hẹn giờ. Điều này xác định khi nào dịch vụ được khởi chạy. Vì vậy, tệp hẹn giờ cần biết về tệp dịch vụ của bạn.

Bộ hẹn giờ có thể là thời gian thực hoặc đơn điệu. Bộ hẹn giờ thời gian thực được kích hoạt bởi các sự kiện lịch. Bộ hẹn giờ đơn điệu được kích hoạt trong một khoảng thời gian nào đó sau một sự kiện hệ thống, chẳng hạn như khởi động. Các mục nhật ký được thêm vào nhật ký hệ thống cho các sự kiện hẹn giờ, điều này có thể giúp gỡ lỗi.

Bạn có thể liệt kê các bộ hẹn giờ trên máy tính của mình bằng cách sử dụng tùy chọn trạng thái của lệnh systemctl. Một số bộ hẹn giờ hệ thống được tạo tự động, vì vậy ngay cả khi bạn chưa tạo bất kỳ bộ hẹn giờ nào, lệnh này sẽ xuất ra.

Mã nguồn [Chọn]
systemctl status "*timer"

Mỗi mô tả chứa các thông tin sau:

  • Tên và mô tả của bộ hẹn giờ, nếu có.
  • Đã tải : Hiển thị trạng thái đã tải. Thông thường bộ đếm thời gian của chúng tôi được đọc và tải vào bộ nhớ. Đường dẫn thư mục đến tập tin hẹn giờ được hiển thị. Chúng tôi mong đợi bộ hẹn giờ của mình được "bật", nhưng nó có thể tạm thời bị "tắt" nếu chúng tôi chọn tắt nó. Giá trị đặt trước của nhà cung cấp cho biết khi bộ hẹn giờ được tạo lần đầu tiên, nó được đặt thành "đã bật" hay "đã tắt".
  • Hoạt động : Hiển thị trạng thái hoạt động, bao gồm ngày và giờ khi bộ hẹn giờ được kích hoạt. Thông thường, bạn sẽ thấy đồng hồ hẹn giờ được liệt kê là "đang hoạt động" và "đang chờ" cho ngày và giờ ra mắt tiếp theo.
  • Until : Thật khó hiểu, dòng này không áp dụng cho bộ tính giờ. Chúng ta có thể bỏ qua nó.
  • Trigger : Hiển thị tên của tiến trình được bộ đếm thời gian khởi chạy.
  • Trình kích hoạt : Hiển thị thời điểm bộ hẹn giờ sẽ được kích hoạt tiếp theo và thời điểm quy trình sẽ được khởi chạy tiếp theo.
  • Tài liệu : Một số đồng hồ có tài liệu liên quan. Dòng này là tùy chọn và không phải lúc nào cũng có.

Vì bộ định thời thực chất là các dịch vụ được kiểm soát thời gian nên chúng ta có thể sử dụng lệnh systemctl để kiểm soát chúng.

3. Tạo bộ đếm thời gian systemd đơn giản

Chữ viết là một phương tiện tĩnh, gây khó khăn cho việc minh họa một quá trình đang được kích hoạt tại một thời điểm cụ thể. Những gì chúng ta sẽ làm là tạo một tập lệnh sẽ được khởi chạy bởi bộ đếm thời gian mới của chúng ta và yêu cầu nó ghi dấu thời gian vào tệp nhật ký. Điều đó sẽ cho chúng tôi biết dịch vụ của chúng tôi đang hoạt động và thời điểm dịch vụ được kích hoạt lần cuối.

Chúng tôi sẽ sử dụng lệnh date để tạo dấu thời gian và chuyển hướng nó đến một tệp có tên "timer.log" trong thư mục chính của chúng tôi.

Chúng ta sẽ tạo tập lệnh trong thư mục "/usr/local/bin/". Chúng tôi đang sử dụng trình chỉnh sửa "gedit", nhưng bạn có thể sử dụng bất kỳ trình chỉnh sửa nào bạn thích.

Mã nguồn [Chọn]
sudo gedit /usr/local/bin/geek-timer.sh
Sao chép những dòng này vào trình chỉnh sửa của bạn, lưu tệp dưới dạng "geek-timer.sh" và đóng trình chỉnh sửa của bạn.

Mã nguồn [Chọn]
#!/bin/bash
echo "Timer fired: $(date)" >> /home/dave/timer.log

Chúng ta sẽ cần làm cho tập lệnh của mình có thể thực thi được.

Mã nguồn [Chọn]
sudo chmod +x /usr/local/bin/geek-timer.sh
Chúng ta hãy kiểm tra xem tập lệnh của chúng ta có thực hiện đúng ý nghĩa của nó hay không.

Mã nguồn [Chọn]
$ geek-timer.sh
$ cat timer.log

Điều đó xác minh rằng tập lệnh của chúng tôi thực thi như mong đợi và đặt dấu thời gian vào tệp "timer.log".

Bây giờ chúng ta sẽ tạo một tệp dịch vụ để xác định dịch vụ mà chúng ta muốn khởi chạy khi bộ hẹn giờ được kích hoạt.

Mã nguồn [Chọn]
sudo gedit /etc/systemd/system/geek-timer.service
Sao chép những dòng này vào trình chỉnh sửa của bạn, lưu tệp dưới dạng "/etc/systemd/system/geek-timer.service" và đóng trình chỉnh sửa của bạn.

Mã nguồn [Chọn]
[Unit]
Description="systemd timer"
Requires=geek-timer.timer

[Service]
Type=simple
ExecStart=/usr/local/bin/geek-timer.sh
User=dave

Phần "[Đơn vị]" có hai dòng. Dòng "Mô tả=" là một dòng đơn giản cho biết dịch vụ của bạn phục vụ mục đích gì. Dòng "Requires=" cho biết rằng dịch vụ này dựa trên tệp hẹn giờ "geek-timer.timer". Chúng ta sẽ tạo tập tin này tiếp theo.

Có thêm một chút thông tin trong phần "[Dịch vụ]". "Type=" là "đơn giản", nghĩa là đây là dịch vụ cơ bản. Các tùy chọn khác bao gồm "oneshot", có nghĩa là dịch vụ chỉ chạy một lần.

Dòng "ExecStart=" cho biết quá trình nào dịch vụ sẽ bắt đầu. Điều này đang trỏ đến tập lệnh mà chúng tôi đã tạo trước đó.

Dòng "User=" xác định người dùng nào sẽ chạy lệnh. Nếu không có điều này, quá trình sẽ được khởi chạy bằng root.

Bây giờ chúng ta sẽ tạo tập tin hẹn giờ. Điều này xác định thời điểm dịch vụ được khởi chạy. Cách tốt nhất là sử dụng cùng tên cơ sở cho các tệp máy chủ và bộ hẹn giờ, với các phần mở rộng khác nhau.

Mã nguồn [Chọn]
sudo gedit /etc/systemd/system/geek-timer.timer
Sao chép những dòng này vào trình chỉnh sửa của bạn, lưu tệp dưới dạng "/etc/systemd/system/geek-timer.timer" và đóng trình chỉnh sửa của bạn.

Mã nguồn [Chọn]
[Unit]
Description="Timer for the geek-timer.service"

[Timer]
Unit=geek-timer.service
OnBootSec=5min
OnUnitActiveSec=1min

[Install]
WantedBy=timers.target

Phần "[Đơn vị]" chứa dòng văn bản "Mô tả=". Phần "[Hẹn giờ]" chứa ba cài đặt. Dòng "Unit=" cho biết dịch vụ nào sẽ được khởi chạy khi bộ hẹn giờ này kích hoạt. Dòng "OnBootSec=" báo cho hệ thống khởi chạy dịch vụ năm phút sau khi máy tính khởi động. Dòng "OnUnitActiveSec=" báo cho bộ hẹn giờ khởi chạy dịch vụ một phút sau lần kích hoạt cuối cùng.

Nói cách khác, năm phút sau khi máy tính khởi động, dịch vụ sẽ khởi chạy. Sau đó, dịch vụ sẽ lặp lại với khoảng thời gian là một phút.

Trong phần "[Cài đặt]", chúng tôi đã thêm dòng "WantedBy=" chỉ định "timers.target." "timers.target" là một đơn vị mục tiêu đặc biệt thiết lập tất cả các đơn vị hẹn giờ hoạt động sau khi khởi động và phù hợp với tất cả các bộ hẹn giờ systemd cơ bản.

Chúng ta có thể sử dụng lệnh trạng thái systemctl để xem bộ đếm thời gian mới của mình.

Mã nguồn [Chọn]
systemctl status geek-timer.service
Không có lỗi nào được báo cáo, đó là điều tốt. Nó không hoạt động vì chúng tôi chưa bắt đầu dịch vụ. Ngay cả khi chúng tôi khởi động lại bây giờ, dịch vụ và bộ hẹn giờ của chúng tôi sẽ không được bật. Hãy bắt đầu và kích hoạt bộ đếm thời gian của chúng tôi.

Mã nguồn [Chọn]
$ sudo systemctl enable geek-timer.timer
$ sudo systemctl start geek-timer.timer

Tôi khởi động lại máy tính thử nghiệm để xem liệu thời gian gia hạn năm phút sau khi khởi động có được tôn trọng hay không và kiểm tra trạng thái của nó một lần nữa.

Mã nguồn [Chọn]
systemctl status geek-timer.service

Điều này cho thấy PC khởi động lúc 12:18 và đồng hồ hẹn giờ của chúng tôi sẽ được kích hoạt lúc 12:23. Yêu cầu của chúng tôi là năm phút sau khi tùy chọn khởi động được xử lý chính xác. Tôi đợi năm phút hết hạn rồi nhanh chóng chạy lệnh tương tự.

Mã nguồn [Chọn]
systemctl status geek-timer.service

Chúng ta có thể thấy rằng thời gian kích hoạt đã di chuyển trong một phút từ 12:23 đến 12:24. Điều này có nghĩa là chúng ta hiện đang ở "giai đoạn lặp lại mỗi phút" của bộ đếm thời gian.

Kiểm tra tệp nhật ký của chúng tôi vài phút sau, cho thấy thời gian kích hoạt ban đầu là 12:23, sau đó các lần khởi chạy tiếp theo diễn ra cách nhau khoảng một phút.

Mã nguồn [Chọn]
cat timer.log

4. Tinh chỉnh thời gian

Thời gian kích hoạt của các sự kiện lặp lại hơi mờ. Đó là lý do tại sao tôi nói các sự kiện trong logfile cách nhau khoảng một phút. Có một yếu tố ngẫu nhiên nhỏ được thêm vào thời gian kích hoạt để đảm bảo rằng các bộ hẹn giờ được lên lịch kích hoạt vào cùng một thời điểm thực sự được kích hoạt theo kiểu so le. Thông thường, đối với các tác vụ như bắt đầu sao lưu hoặc các hoạt động quản lý hệ thống khác, điều đó là đủ chính xác.

Nếu bạn cần độ phân giải chặt chẽ hơn, bạn có thể sử dụng thời gian micro giây. Việc thêm dòng này vào phần "[Timer]" trong tệp bộ đếm thời gian của bạn sẽ đặt hệ thống sử dụng độ phân giải một phần triệu giây.

Mã nguồn [Chọn]
AccuracySec=1us
Đây là các cài đặt độ chính xác mà bạn có thể sử dụng và cách bạn có thể tham khảo chúng.

  • Micro giây : chúng tôi, µs msec, ms
  • Giây : giây, giây, giây, s
  • Phút : phút, phút, phút, m
  • Giờ : giờ, giờ, giờ, h
  • Ngày : ngày, ngày, d
  • Tuần : tuần, tuần, w
  • Tháng : tháng, tháng, M
  • Năm : năm, năm, y

Bạn có thể kích hoạt bộ hẹn giờ vào một ngày và giờ cụ thể bằng cách sử dụng cài đặt "OnCalendar". Điều này nằm trong phần "[Timer]" của tệp hẹn giờ. Định dạng chung là:

Mã nguồn [Chọn]
OnCalendar=DayOfTheWeek YYYY-MM-DD HH:MM:SS
DayOfTheWeek là tùy chọn. Bất kỳ giá trị nào khác được thay thế bằng dấu hoa thị '*' có nghĩa là "mỗi", như mỗi phút hoặc mỗi giờ. Bạn có thể sử dụng tên hoặc số cho ngày và tháng cũng như danh sách được phân tách bằng dấu phẩy để thể hiện các lựa chọn giá trị. Phạm vi giá trị được biểu thị bằng cách sử dụng hai dấu chấm ".." để phân tách phần đầu và giá trị của phạm vi.

Điều này sẽ đặt bộ hẹn giờ để kích hoạt lúc 01:15 vào Thứ Sáu đầu tiên của mỗi tháng.

Mã nguồn [Chọn]
OnCalendar=Fri *-*-1..7 01:15:00
Điều này sẽ chạy một quá trình vào lúc 19:00 mỗi ngày.

Mã nguồn [Chọn]
OnCalendar=*-*-* 19:00:00
Một bộ hẹn giờ có thể có nhiều bộ thời gian kích hoạt. Điều này sẽ chạy một quy trình vào thời điểm khác trong ngày làm việc và vào cuối tuần.

Mã nguồn [Chọn]
OnCalendar=Mon..Fri 23:00:00
OnCalendar=Sat,Sun 19:00:00

Trang systemd time man mô tả đầy đủ các định dạng thời gian và nhiều mẹo và thủ thuật hữu ích.

5. Tính linh hoạt và dễ sử dụng tuyệt vời

Phần lớn tính linh hoạt của bộ tính giờ systemd nằm ở cách bạn có thể phục vụ cho các sự kiện lịch lẻ. Ví dụ: để đặt bộ hẹn giờ kích hoạt lúc 15:00 vào tất cả các ngày ngoại trừ Thứ Sáu, bạn có thể sử dụng định dạng sau:

Mã nguồn [Chọn]
Mon..Thu,Sat,Sun *-*-* 15:00:00
Bằng cách kết hợp các danh sách và phạm vi được phân tách bằng dấu phẩy, bạn sẽ thấy dễ dàng tạo trình kích hoạt theo thời gian thực cho mọi loại yêu cầu phức tạp.

Khi bạn đã có ý tưởng rằng bạn tạo một dịch vụ để khởi chạy quy trình của mình và tệp hẹn giờ để quản lý việc khởi chạy dịch vụ, bạn đã hiểu được 90% về bộ tính giờ của systemd. 10 phần trăm cuối cùng đang nắm lấy sức mạnh duyên dáng của các sự kiện trên lịch.