歡迎光臨
每天分享高質量文章

在 Linux 上使用 systemd 設定定時器 | Linux 中國

學習使用 systemd 建立啟動你的遊戲伺服器的定時器。
— Paul Brown


致謝
編譯自 | 
https://www.linux.com/blog/learn/intro-to-linux/2018/7/setting-timer-systemd-linux
 
 作者 | Paul Brown
 譯者 | LuMing (LuuMing) ??共計翻譯:6.0 篇 貢獻時間:65 天

學習使用 systemd 建立啟動你的遊戲伺服器的定時器。

之前,我們看到瞭如何手動的[1]在開機與關機時[2]在啟用某個裝置時[3]在檔案系統發生改變時[4] 啟用與禁用 systemd 服務。

定時器增加了另一種啟動服務的方式,基於……時間。儘管與定時任務很相似,但 systemd 定時器稍微地靈活一些。讓我們看看它是怎麼工作的。

“定時執行”

讓我們展開本系列前兩篇文章[2]你所設定的[1] Minetest[5] 伺服器作為如何使用定時器單元的第一個例子。如果你還沒有讀過那幾篇文章,可以現在去看看。

你將透過建立一個定時器來“改進” Minetest 伺服器,使得在伺服器啟動 1 分鐘後運行遊戲伺服器而不是立即執行。這樣做的原因可能是,在啟動之前可能會用到其他的服務,例如發郵件給其他玩家告訴他們遊戲已經準備就緒,你要確保其他的服務(例如網路)在開始前完全啟動並執行。

最終,你的 minetest.timer 單元看起來就像這樣:

  1. # minetest.timer

  2. [Unit]

  3. Description=Runs the minetest.service 1 minute after boot up

  4. [Timer]

  5. OnBootSec=1 m

  6. Unit=minetest.service

  7. [Install]

  8. WantedBy=basic.target

一點也不難吧。

如以往一般,開頭是 [Unit] 和一段描述單元作用的資訊,這兒沒什麼新東西。[Timer] 這一節是新出現的,但它的作用不言自明:它包含了何時啟動服務,啟動哪個服務的資訊。在這個例子當中,OnBootSec 是告訴 systemd 在系統啟動後執行服務的指令。

其他的指令有:

◈ OnActiveSec=,告訴 systemd 在定時器啟動後多長時間執行服務。
◈ OnStartupSec=,同樣的,它告訴 systemd 在 systemd 行程啟動後多長時間執行服務。
◈ OnUnitActiveSec=,告訴 systemd 在上次由定時器啟用的服務啟動後多長時間執行服務。
◈ OnUnitInactiveSec=,告訴 systemd 在上次由定時器啟用的服務停用後多長時間執行服務。

繼續 minetest.timer 單元,basic.target 通常用作後期引導服務late boot services同步點synchronization point。這就意味著它可以讓 minetest.timer 單元執行在安裝完本地掛載點local mount points或交換裝置,套接字、定時器、路徑單元和其他基本的初始化行程之後。就像在第二篇文章中 systemd 單元[2]裡解釋的那樣,targets 就像舊的執行等級old run levels一樣,可以將你的計算機置於某個狀態,或像這樣告訴你的服務在達到某個狀態後開始執行。

在前兩篇文章中你配置的 minetest.service 檔案最終[2]看起來就像這樣:

  1. # minetest.service

  2. [Unit]

  3. Description= Minetest server

  4. Documentation= https://wiki.minetest.net/Main_Page

  5. [Service]

  6. Type= simple

  7. User=

  8. ExecStart= /usr/games/minetest --server

  9. ExecStartPost= /home//bin/mtsendmail.sh "Ready to rumble?" "Minetest Starting up"

  10. TimeoutStopSec= 180

  11. ExecStop= /home//bin/mtsendmail.sh "Off to bed. Nightie night!" "Minetest Stopping in 2 minutes"

  12. ExecStop= /bin/sleep 120

  13. ExecStop= /bin/kill -2 $MAINPID

  14. [Install]

  15. WantedBy= multi-user.target

這兒沒什麼需要修改的。但是你需要將 mtsendmail.sh(傳送你的 email 的指令碼)從:

  1. #!/bin/bash

  2. # mtsendmail

  3. sleep 20

  4. echo $1 | mutt -F /home/<username>/.muttrc -s "$2" my_minetest@mailing_list.com

  5. sleep 10

改成:

  1. #!/bin/bash

  2. # mtsendmail.sh

  3. echo $1 | mutt -F /home/paul/.muttrc -s "$2" pbrown@mykolab.com

你做的事是去除掉 Bash 指令碼中那些蹩腳的停頓。Systemd 現在來做等待。

讓它執行起來

確保一切運作正常,禁用 minetest.service

  1. sudo systemctl disable minetest

這使得系統啟動時它不會一同啟動;然後,相反地,啟用 minetest.timer

  1. sudo systemctl enable minetest.timer

現在你就可以重啟伺服器了,當執行 sudo journalctl -u minetest.* 後,你就會看到 minetest.timer 單元執行後大約一分鐘,minetest.service 單元開始執行。

圖 1:minetest.timer 執行大約 1 分鐘後 minetest.service 開始執行

時間的問題

minetest.timer 在 systemd 的日誌裡顯示的啟動時間為 09:08:33 而 minetest.service 啟動時間是 09:09:18,它們之間少於 1 分鐘,關於這件事有幾點需要說明一下:首先,請記住我們說過 OnBootSec= 指令是從引導完成後開始計算服務啟動的時間。當 minetest.timer 的時間到來時,引導已經在幾秒之前完成了。

另一件事情是 systemd 給自己設定了一個誤差幅度margin of error(預設是 1 分鐘)來執行東西。這有助於在多個資源密集型行程resource-intensive processes同時執行時分配負載:透過分配 1 分鐘的時間,systemd 可以等待某些行程關閉。這也意味著 minetest.service 會在引導完成後的 1~2 分鐘之間啟動。但精確的時間誰也不知道。

順便一提,你可以用 AccuracySec= 指令修改誤差幅度[6]

你也可以檢查系統上所有的定時器何時執行或是上次執行的時間:

  1. systemctl list-timers --all

圖 2:檢查定時器何時執行或上次執行的時間

最後一件值得思考的事就是你應該用怎樣的格式去表示一段時間。Systemd 在這方面非常靈活:2 h2 hours 或 2hr 都可以用來表示 2 個小時。對於“秒”,你可以用 secondssecondsec 和 s。“分”也是同樣的方式:minutesminutemin 和 m。你可以檢查 man systemd.time 來檢視 systemd 能夠理解的所有時間單元。

下一次

下次你會看到如何使用日曆中的日期和時間來定期執行服務,以及如何透過組合定時器與裝置單元在插入某些硬體時執行服務。

回頭見!

在 Linux 基金會和 edx 上透過免費課程 “Introduction to Linux”[7] 學習更多關於 Linux 的知識。


via: https://www.linux.com/blog/learn/intro-to-linux/2018/7/setting-timer-systemd-linux

作者:Paul Brown[9] 選題:lujun9972 譯者:LuuMing 校對:wxy

本文由 LCTT 原創編譯,Linux中國 榮譽推出

贊(0)

分享創造快樂

© 2024 知識星球   網站地圖