Go語(yǔ)言中定時(shí)器cron的基本使用教程
cron是什么
cron的意思就是:計(jì)劃任務(wù),說(shuō)白了就是定時(shí)任務(wù)。我和系統(tǒng)約個(gè)時(shí)間,你在幾點(diǎn)幾分幾秒或者每隔幾分鐘跑一個(gè)任務(wù)(job),就那么簡(jiǎn)單。
前言
cron 是 robfig 開(kāi)發(fā)的一個(gè)定時(shí)作業(yè)庫(kù),robfig 總是想的比別人早,給了我們這些 Gopher 不少急需的東西,想當(dāng)年 revel 的出現(xiàn)也是這樣的??纯?cron 的使用,還是一如既往的簡(jiǎn)潔明了,發(fā)現(xiàn) Go 的世界里,有些產(chǎn)品還是有鮮明的個(gè)人特質(zhì)的,那就是所謂的個(gè)人魅力吧?!
總之 robfig 開(kāi)發(fā)的產(chǎn)品都是有一定超前性,比較有理論基礎(chǔ),使用起來(lái)很簡(jiǎn)單的東西。
下面看看怎么用 cron 吧:
c := cron.New()
c.AddFunc("0 30 * * * *", func() { fmt.Println("Every hour on the half hour") })
c.AddFunc("@hourly", func() { fmt.Println("Every hour") })
c.AddFunc("@every 1h30m", func() { fmt.Println("Every hour thirty") })
c.Start()
首先實(shí)例化一個(gè) cron 對(duì)象 c,然后調(diào)用實(shí)例 c 的 AddFunc 函數(shù),AddFunc 函數(shù)接收一個(gè)定時(shí)表達(dá)式和一個(gè)普通函數(shù),最后開(kāi)始執(zhí)行實(shí)例,定時(shí)作業(yè)就好了。
首先接收的普通函數(shù),就是我們業(yè)務(wù)的東西了,比如我們想打印 Hello World! 一行字符串,我們這么寫(xiě)這樣的函數(shù):
func PrintSomeWord(){
fmt.Sprint("Hello World!")
}
PrintSomeWord 寫(xiě)好了,接下來(lái)想每秒鐘打印一次,這時(shí) cron 就派上用場(chǎng)了:
c := cron.New()
c.AddFunc("@every 1s",PrintSomeWord)
c.Start()
這么說(shuō)來(lái),普通函數(shù)是隨我們的業(yè)務(wù)決定的,我們暫且不談了,而定時(shí)表達(dá)式才是我們要學(xué)習(xí)的東西。我們從 cron 的名字,很容易聯(lián)想到 Linux 系統(tǒng)的 cron 定時(shí)器來(lái),它們是不是存在一定的關(guān)系呢?從下面的使用情況來(lái)看,答案是的。仔細(xì)看它們的定時(shí)表達(dá)式是非常相似的,這樣就好辦了,大大降低了使用 cron 的門(mén)檻,畢竟 Linux 的 cron 是一個(gè)標(biāo)準(zhǔn)來(lái)的。
我們看看 cron 普通的表達(dá)式:
c.AddFunc("@every 1h30m", func() { fmt.Println("Every hour thirty") })
c.AddFunc("@daily", func() { fmt.Println("Every day") })
c.AddFunc("@hourly", func() { fmt.Println("Every hour") })
這三行代碼的定時(shí)表達(dá)式分別表示:每1小時(shí)30分鐘執(zhí)行一次,每天執(zhí)行一次,每小時(shí)執(zhí)行一次。
@every 很廣,修改后綴,就可以表示不同的用途,比如 秒 分 小時(shí) 天,看看代碼:
@every 1s @every 1m @every 1h @every 1d
怎么樣很有規(guī)律吧?
更往深一點(diǎn),可能就是嫌棄 @every 還不夠簡(jiǎn)潔了,比如:
@every 1h @every 1d @every 30d
每小時(shí) 每天 每月 完全可以不用后綴了:
@hourly @daily @monthly
當(dāng)然簡(jiǎn)潔是好的,但簡(jiǎn)潔的同時(shí)往往也有些無(wú)法做到簡(jiǎn)潔的情況,比如上面提到的:
@every 1h30m
不用后綴是不行了吧?
最不好理解的可能是以下的表達(dá)式了,因?yàn)榭催@種表達(dá)式,就好比看一堆正則表達(dá)式一樣,讓一般人懵逼:
c.AddFunc("0 30 * * * *", func() { fmt.Println("Every hour on the half hour") })
定時(shí)表達(dá)式 0 30 * * * * 到底是什么意思???第一印象,毫無(wú)規(guī)律性,不知道什么意思,如果翻譯 Every hour on the half hour 這句洋文,倒是有點(diǎn)概念了,意思就是“每一小時(shí)半(1.5個(gè)小時(shí))執(zhí)行一次” 嘛?。?!
額,看到0 30和六個(gè)占位數(shù),推理一下:是不是 秒 分 時(shí) 天 月 年 ?。克坪跤忻济?,我也想知道這個(gè)表達(dá)式的具體使用辦法,只能下次認(rèn)真學(xué)習(xí)后,一起說(shuō)道說(shuō)道了。
Go 定時(shí)器 cron 表達(dá)式的使用
如果想更靈活的使用定時(shí),可能會(huì)涉及到更復(fù)雜的六位表達(dá)式的使用方法,如每半小時(shí)執(zhí)行一次:
0 30 * * * *
六位的表達(dá)式看起來(lái),有點(diǎn)費(fèi)解,好比正則表達(dá)式一樣,我們需要按步驟來(lái)理解;
理解六個(gè)作用域的意義
0 0 0 1 1 * 0 0 0 1 * * 0 0 0 * * 0 0 0 0 * * * 0 0 * * * *
如上表達(dá)式,都是六位占位符,可以是數(shù)字和字符,其中字符是特定字符包括:【* / , - ? JAN-DEC SUN-SAT】
我們叫它為六個(gè)作用域吧,從左到右的順序,代表的含義是 秒鐘域(1) 分鐘域(2) 小時(shí)域(3) 日期域(4) 月份域(5) 星期域(6)
月份域可以使用 JAN-DEC 和星期域可以使用SUN-SAT,分別表示 1-12月的英文縮寫(xiě)和星期一至星期日的英文簡(jiǎn)寫(xiě),如果不了解月份和星期英文簡(jiǎn)寫(xiě),建議使用數(shù)字表示,因?yàn)檫@個(gè)需要記憶和大小寫(xiě)敏感的,容易出錯(cuò)。
下面列出方便理解:
1至12月份的英文簡(jiǎn)寫(xiě):Jan Feb Mar Apr May Jun Jul Aug Sept Oct Nov Dec
星期一至星期日的英文簡(jiǎn)寫(xiě):Mon Tues Wed Thurs Fri Sat Sun
六個(gè)作用域還可以使用的特定字符:
特定字符星號(hào)( *)
星號(hào)表示匹配所有合理的值,可以存在任何域。比如第月份域(5)的位置使用星號(hào)*,表示每個(gè)月都執(zhí)行;同理在星期域(6)的位置使用星號(hào),表示每個(gè)星期都執(zhí)行;其他占位使用它以此類(lèi)推。
特定字符斜劃線(xiàn) (/)
斜劃線(xiàn)通常用于一個(gè)范圍增量,可以存在任何域。比如在分鐘域(2)的位置使用 3-59/15 表示一個(gè)小時(shí)的第3分鐘到59分鐘時(shí)間范圍內(nèi),每15分鐘執(zhí)行一次。
特定字符逗號(hào) (,)
逗號(hào)用于分隔多個(gè)點(diǎn),可以存在任何域。比如在星期域(6)的位置使用 MON,WED,FRI 表示星期一、星期三、星期五這三個(gè)點(diǎn)都滿(mǎn)足條件。
特定字符中橫杠 (-)
中橫杠通常用于定義范圍,可以存在任何域。 例如小時(shí)域(3)的位置使用 9-17 表示起始9點(diǎn)到截止17點(diǎn)這個(gè)時(shí)間段范圍。
特定字符問(wèn)號(hào) (?)
問(wèn)號(hào)表示不確定一個(gè)點(diǎn)的意思,只能在日期域(4) 星期域(6)的位置使用,表示指定的值不確定性,一個(gè)表達(dá)式中只能用一次問(wèn)號(hào)?,如果在日期域(4)使用了,就不能再星期域(6)上用了。它和星號(hào)是有區(qū)別的,星號(hào)表示匹配所有點(diǎn),就是說(shuō)一個(gè)月哪一天,哪個(gè)星期都可以,而問(wèn)號(hào),表示一個(gè)月的不確定哪一天或是一周不確定哪一天都行,這個(gè)是很難理解的,需要說(shuō)一些具體的情況來(lái)解釋?zhuān)热?月的第18天,剛好是第三周的第2天,那么如果在日期域(4)定義18,星期域(6)定義2這樣就重疊定義了,這個(gè) cron 是不允許的。
總結(jié)
以上就是這篇文章的全部?jī)?nèi)容了,希望本文的內(nèi)容對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,如果有疑問(wèn)大家可以留言交流,謝謝大家對(duì)腳本之家的支持。
相關(guān)文章
Windows下Goland的環(huán)境搭建過(guò)程詳解
這篇文章主要介紹了Windows下Goland的環(huán)境搭建過(guò)程,本文通過(guò)圖文并茂的形式給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2020-10-10
Go語(yǔ)言如何使用golang-jwt/jwt/v4進(jìn)行JWT鑒權(quán)詳解
最近項(xiàng)目中需要用到鑒權(quán)機(jī)制,golang中jwt可以用,這篇文章主要給大家介紹了關(guān)于Go語(yǔ)言如何使用golang-jwt/jwt/v4進(jìn)行JWT鑒權(quán)的相關(guān)資料,需要的朋友可以參考下2022-09-09
Go在GoLand中引用github.com中的第三方包具體步驟
這篇文章主要給大家介紹了關(guān)于Go在GoLand中引用github.com中第三方包的具體步驟,文中通過(guò)圖文介紹的非常詳細(xì),對(duì)大家學(xué)習(xí)或者使用Go具有一定的參考價(jià)值,需要的朋友可以參考下2024-01-01
Go語(yǔ)言學(xué)習(xí)之條件語(yǔ)句使用詳解
這篇文章主要介紹了Go語(yǔ)言中條件語(yǔ)句的使用,本文給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2022-04-04
Go利用反射reflect實(shí)現(xiàn)獲取接口變量信息
反射是通過(guò)實(shí)體對(duì)象獲取反射對(duì)象(Value、Type),然后可以操作相應(yīng)的方法。本文將利用Go語(yǔ)言中的反射reflect實(shí)現(xiàn)獲取接口變量信息,需要的可以參考一下2022-05-05
Go語(yǔ)言實(shí)現(xiàn)釘釘發(fā)送通知
本文通過(guò)代碼給大家介紹了Go語(yǔ)言實(shí)現(xiàn)釘釘發(fā)送通知,代碼簡(jiǎn)單易懂,非常不錯(cuò),具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2019-11-11
Go語(yǔ)言Gin框架實(shí)現(xiàn)HTML頁(yè)面渲染
Web開(kāi)發(fā)中,我們經(jīng)常要面對(duì)如何將數(shù)據(jù)渲染到前端的問(wèn)題,這就涉及到了模板引擎的知識(shí),Go語(yǔ)言的Gin框架就提供了強(qiáng)大的HTML模板渲染功能,本文就來(lái)為大家介紹,有需要的朋友可以借鑒參考下,希望能夠有所幫助2024-01-01
解決Golang time.Parse和time.Format的時(shí)區(qū)問(wèn)題
這篇文章主要介紹了解決Golang time.Parse和time.Format的時(shí)區(qū)問(wèn)題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧2021-04-04

