自拍偷在线精品自拍偷,亚洲欧美中文日韩v在线观看不卡

Systemd定時(shí)器:三種使用場景

系統(tǒng) Linux
在這個(gè) systemd 系列教程中,我們已經(jīng)在某種程度上討論了 systemd 定時(shí)器單元。不過,在我們開始討論 sockets 之前,我們先來看三個(gè)例子,這些例子展示了如何最佳化利用這些單元。

[[251312]]

繼續(xù) systemd 教程,這些特殊的例子可以展示給你如何更好的利用 systemd 定時(shí)器單元。

在這個(gè) systemd 系列教程中,我們已經(jīng)在某種程度上討論了 systemd 定時(shí)器單元。不過,在我們開始討論 sockets 之前,我們先來看三個(gè)例子,這些例子展示了如何***化利用這些單元。

簡單的類 cron 行為

我每周都要去收集 Debian popcon 數(shù)據(jù),如果每次都能在同一時(shí)間收集更好,這樣我就能看到某些應(yīng)用程序的下載趨勢。這是一個(gè)可以使用 cron 任務(wù)來完成的典型事例,但 systemd 定時(shí)器同樣能做到:

  1. # cron popcon.timer
  2.  
  3. [Unit]
  4. Description= 這里描述了下載并處理 popcon 數(shù)據(jù)的時(shí)刻
  5.  
  6. [Timer]
  7. OnCalendar= Thu *-*-* 05:32:07
  8. Unit= popcon.service
  9.  
  10. [Install]
  11. WantedBy= basic.target

實(shí)際的 popcon.service 會(huì)執(zhí)行一個(gè)常規(guī)的 wget 任務(wù),并沒有什么特別之處。這里的新內(nèi)容是 OnCalendar= 指令。這個(gè)指令可以讓你在一個(gè)特定日期的特定時(shí)刻來運(yùn)行某個(gè)服務(wù)。在這個(gè)例子中,Thu 表示 “在周四運(yùn)行”,*-*-* 表示“具體年份、月份和日期無關(guān)緊要”,這些可以翻譯成 “不管年月日,只在每周四運(yùn)行”。

這樣,你就設(shè)置了這個(gè)服務(wù)的運(yùn)行時(shí)間。我選擇在歐洲中部夏令時(shí)區(qū)的上午 5:30 左右運(yùn)行,那個(gè)時(shí)候服務(wù)器不是很忙。

如果你的服務(wù)器關(guān)閉了,而且剛好錯(cuò)過了每周的截止時(shí)間,你還可以在同一個(gè)計(jì)時(shí)器中使用像 anacron 一樣的功能。

  1. # 具備類似 anacron 功能的 popcon.timer
  2.  
  3. [Unit]
  4. Description= 這里描述了下載并處理 popcon 數(shù)據(jù)的時(shí)刻
  5.  
  6. [Timer]
  7. Unit=popcon.service
  8. OnCalendar=Thu *-*-* 05:32:07
  9. Persistent=true
  10.  
  11. [Install]
  12. WantedBy=basic.target

當(dāng)你將 Persistent= 指令設(shè)為真值時(shí),它會(huì)告訴 systemd,如果服務(wù)器在本該它運(yùn)行的時(shí)候關(guān)閉了,那么在啟動(dòng)后就要立刻運(yùn)行服務(wù)。這意味著,如果機(jī)器在周四凌晨停機(jī)了(比如說維護(hù)),一旦它再次啟動(dòng)后,popcon.service 將會(huì)立刻執(zhí)行。在這之后,它的運(yùn)行時(shí)間將會(huì)回到例行性的每周四早上 5:32.

到目前為止,就是這么簡單直白。

延遲執(zhí)行

但是,我們提升一個(gè)檔次,來“改進(jìn)”這個(gè)基于 systemd 的監(jiān)控系統(tǒng)。你應(yīng)該記得,當(dāng)你接入攝像頭的時(shí)候,系統(tǒng)就會(huì)開始拍照。假設(shè)你并不希望它在你安裝攝像頭的時(shí)候拍下你的臉。你希望將拍照服務(wù)的啟動(dòng)時(shí)間向后推遲一兩分鐘,這樣你就有時(shí)間接入攝像頭,然后走到畫框外面。

為了完成這件事,首先你要更改 Udev 規(guī)則,將它指向一個(gè)定時(shí)器:

  1. ACTION=="add", SUBSYSTEM=="video4linux", ATTRS{idVendor}=="03f0",
  2. ATTRS{idProduct}=="e207", TAG+="systemd", ENV{SYSTEMD_WANTS}="picchanged.timer",
  3. SYMLINK+="mywebcam", MODE="0666"

這個(gè)定時(shí)器看起來像這樣:

  1. # picchanged.timer
  2.  
  3. [Unit]
  4. Description= 在攝像頭接入的一分鐘后,開始運(yùn)行 picchanged
  5.  
  6. [Timer]
  7. OnActiveSec= 1 m
  8. Unit= picchanged.path
  9.  
  10. [Install]
  11. WantedBy= basic.target

在你接入攝像頭后,Udev 規(guī)則被觸發(fā),它會(huì)調(diào)用定時(shí)器。這個(gè)定時(shí)器啟動(dòng)后會(huì)等上一分鐘(OnActiveSec= 1 m),然后運(yùn)行 picchanged.path,它會(huì)監(jiān)視主圖片的變化。picchanged.path 還會(huì)負(fù)責(zé)接觸 webcan.service,這個(gè)實(shí)際用來拍照的服務(wù)。

在每天的特定時(shí)刻啟停 Minetest 服務(wù)器

在***一個(gè)例子中,我們認(rèn)為你決定用 systemd 作為唯一的依賴。講真,不管怎么樣,systemd 差不多要接管你的生活了。為什么不擁抱這個(gè)必然性呢?

你有個(gè)為你的孩子設(shè)置的 Minetest 服務(wù)。不過,你還想要假裝關(guān)心一下他們的教育和成長,要讓他們做作業(yè)和家務(wù)活。所以你要確保 Minetest 只在每天晚上的一段時(shí)間內(nèi)可用,比如五點(diǎn)到七點(diǎn)。

這個(gè)跟之前的“在特定時(shí)間啟動(dòng)服務(wù)”不太一樣。寫個(gè)定時(shí)器在下午五點(diǎn)啟動(dòng)服務(wù)很簡單…:

  1. # minetest.timer
  2.  
  3. [Unit]
  4. Description= 在每天下午五點(diǎn)運(yùn)行 minetest.service
  5.  
  6. [Timer]
  7. OnCalendar= *-*-* 17:00:00
  8. Unit= minetest.service
  9.  
  10. [Install]
  11. WantedBy= basic.target

…可是編寫一個(gè)對應(yīng)的定時(shí)器,讓它在特定時(shí)刻關(guān)閉服務(wù),則需要更大劑量的橫向思維。

我們從最明顯的東西開始 —— 設(shè)置定時(shí)器:

  1. # stopminetest.timer
  2.  
  3. [Unit]
  4. Description= 每天晚上七點(diǎn)停止 minetest.service
  5.  
  6. [Timer]
  7. OnCalendar= *-*-* 19:05:00
  8. Unit= stopminetest.service
  9.  
  10. [Install]
  11. WantedBy= basic.target

這里棘手的部分是如何去告訴 stopminetest.service 去 —— 你知道的 —— 停止 Minetest. 我們無法從 minetest.service 中傳遞 Minetest 服務(wù)器的 PID. 而且 systemd 的單元詞匯表中也沒有明顯的命令來停止或禁用正在運(yùn)行的服務(wù)。

我們的訣竅是使用 systemd 的 Conflicts= 指令。它和 systemd 的 Wants= 指令類似,不過它所做的事情正相反。如果你有一個(gè) b.service 單元,其中包含一個(gè) Wants=a.service 指令,在這個(gè)單元啟動(dòng)時(shí),如果 a.service 沒有運(yùn)行,則 b.service 會(huì)運(yùn)行它。同樣,如果你的 b.service 單元中有一行寫著 Conflicts= a.service,那么在 b.service 啟動(dòng)時(shí),systemd 會(huì)停止 a.service.

這種機(jī)制用于兩個(gè)服務(wù)在嘗試同時(shí)控制同一資源時(shí)會(huì)發(fā)生沖突的場景,例如當(dāng)兩個(gè)服務(wù)要同時(shí)訪問打印機(jī)的時(shí)候。通過在***服務(wù)中設(shè)置 Conflicts=,你就可以確保它會(huì)覆蓋掉最不重要的服務(wù)。

不過,你會(huì)在一個(gè)稍微不同的場景中來使用 Conflicts=. 你將使用 Conflicts= 來干凈地關(guān)閉 minetest.service

  1. # stopminetest.service
  2.  
  3. [Unit]
  4. Description= 關(guān)閉 Minetest 服務(wù)
  5. Conflicts= minetest.service
  6.  
  7. [Service]
  8. Type= oneshot
  9. ExecStart= /bin/echo "Closing down minetest.service"

stopminetest.service 并不會(huì)做特別的東西。事實(shí)上,它什么都不會(huì)做。不過因?yàn)樗切?Conflicts=,所以在它啟動(dòng)時(shí),systemd 會(huì)關(guān)掉 minetest.service.

在你***的 Minetest 設(shè)置中,還有***一點(diǎn)漣漪:你下班晚了,錯(cuò)過了服務(wù)器的開機(jī)時(shí)間,可當(dāng)你開機(jī)的時(shí)候游戲時(shí)間還沒結(jié)束,這該怎么辦?Persistent= 指令(如上所述)在錯(cuò)過開始時(shí)間后仍然可以運(yùn)行服務(wù),但這個(gè)方案還是不行。如果你在早上十一點(diǎn)把服務(wù)器打開,它就會(huì)啟動(dòng) Minetest,而這不是你想要的。你真正需要的是一個(gè)確保 systemd 只在晚上五到七點(diǎn)啟動(dòng) Minetest 的方法:

  1. # minetest.timer
  2.  
  3. [Unit]
  4. Description= 在下午五到七點(diǎn)內(nèi)的每分鐘都運(yùn)行 minetest.service
  5.  
  6. [Timer]
  7. OnCalendar= *-*-* 17..19:*:00
  8. Unit= minetest.service
  9.  
  10. [Install]
  11. WantedBy= basic.target

OnCalendar= *-*-* 17..19:*:00 這一行有兩個(gè)有趣的地方:(1) 17..19 并不是一個(gè)時(shí)間點(diǎn),而是一個(gè)時(shí)間段,在這個(gè)場景中是 17 到 19 點(diǎn);以及,(2) 分鐘字段中的 * 表示服務(wù)每分鐘都要運(yùn)行。因此,你會(huì)把它讀做 “在下午五到七點(diǎn)間的每分鐘,運(yùn)行 minetest.service”

不過還有一個(gè)問題:一旦 minetest.service 啟動(dòng)并運(yùn)行,你會(huì)希望 minetest.timer 不要再次嘗試運(yùn)行它。你可以在 minetest.service 中包含一條 Conflicts= 指令:

  1. # minetest.service
  2.  
  3. [Unit]
  4. Description= 運(yùn)行 Minetest 服務(wù)器
  5. Conflicts= minetest.timer
  6.  
  7. [Service]
  8. Type= simple
  9. User= <your user name>
  10.  
  11. ExecStart= /usr/bin/minetest --server
  12. ExecStop= /bin/kill -2 $MAINPID
  13.  
  14. [Install]
  15. WantedBy= multi-user.targe

上面的 Conflicts= 指令會(huì)保證在 minstest.service 成功運(yùn)行后,minetest.timer 就會(huì)立即停止。

現(xiàn)在,啟用并啟動(dòng) minetest.timer

  1. systemctl enable minetest.timer
  2. systemctl start minetest.timer

而且,如果你在六點(diǎn)鐘啟動(dòng)了服務(wù)器,minetest.timer 會(huì)啟用;到了五到七點(diǎn),minetest.timer 每分鐘都會(huì)嘗試啟動(dòng) minetest.service。不過,一旦 minetest.service 開始運(yùn)行,systemd 會(huì)停止 minetest.timer,因?yàn)樗鼤?huì)與 minetest.service “沖突”,從而避免計(jì)時(shí)器在服務(wù)已經(jīng)運(yùn)行的情況下還會(huì)不斷嘗試啟動(dòng)服務(wù)。

在首先啟動(dòng)某個(gè)服務(wù)時(shí)殺死啟動(dòng)它的計(jì)時(shí)器,這么做有點(diǎn)反直覺,但它是有效的。

總結(jié)

你可能會(huì)認(rèn)為,有更好的方式來做上面這些事。我在很多文章中看到過“過度設(shè)計(jì)”這個(gè)術(shù)語,尤其是在用 systemd 定時(shí)器來代替 cron 的時(shí)候。

但是,這個(gè)系列文章的目的不是為任何具體問題提供***解決方案。它的目的是為了盡可能多地使用 systemd 來解決問題,甚至?xí)交奶频某潭取K哪康氖钦故敬罅康睦?,來說明如何利用不同類型的單位及其包含的指令。我們的讀者,也就是你,可以從這篇文章中找到所有這些的可實(shí)踐范例。

盡管如此,我們還有一件事要做:下回中,我們會(huì)關(guān)注 sockets 和 targets,然后我們將完成對 systemd 單元的介紹。 

責(zé)任編輯:龐桂玉 來源: Linux中國
相關(guān)推薦

2021-04-18 12:12:29

systemd定時(shí)器系統(tǒng)運(yùn)維

2018-11-02 08:10:58

Linuxsystemd定時(shí)器

2016-09-12 14:07:14

Android 定時(shí)器

2021-06-28 06:00:11

systemd定時(shí)器系統(tǒng)運(yùn)維

2013-07-29 10:10:40

TCP協(xié)議TCP定時(shí)器TCP

2009-11-11 10:14:10

linux定時(shí)器操作系統(tǒng)

2014-12-09 16:30:18

TCP定時(shí)器

2024-05-15 08:49:23

.NET定時(shí)器UI線程

2022-09-20 07:36:43

云原生存儲方案

2023-08-02 09:26:03

軟件定時(shí)器鴻蒙

2015-10-13 15:05:09

BYOD自帶設(shè)備移動(dòng)辦公

2015-09-25 11:08:44

移動(dòng)辦公BYOD

2009-06-15 15:02:48

Spring定時(shí)器

2015-10-15 09:38:48

TCP網(wǎng)絡(luò)協(xié)議定時(shí)器

2021-08-03 14:33:53

cron定時(shí)器Linux命令

2023-12-11 09:50:35

Linux定時(shí)器

2025-01-08 09:55:37

Spring接口數(shù)據(jù)庫

2010-07-28 15:56:22

FlexTimer定時(shí)

2023-03-27 18:33:47

客服IM消息

2024-09-20 05:49:04

SpringBoot后端
點(diǎn)贊
收藏

51CTO技術(shù)棧公眾號