golang 實現定時任務 cron
阿新 • • 發佈:2020-07-18
1. 安裝cron
go get -u github.com/robfig/cron
2. 先看一個例子
這個例子將會每秒鐘列印 一次hello world
package main import ( "fmt" "github.com/robfig/cron" "time" ) func main (){ c := cron.New() _ = c.AddFunc("* * * * * *", func() { fmt.Println("hello world") }) c.Start() time.Sleep(10 * time.Second) }
做幾點說明:
- cron.New() 建立一個cron物件
- cron物件通過AddFunc方法將一個函式按指定的時間計劃執行
* * * * * *
就是我們的時間計劃,這是指每秒執行一次,後面在詳細講- Start() 方法開始執行
- time.Sleep(10 * time.Second) 防止主goroutine退出否則這個程式就會結束,任務將會無法執行
3. 解決你的疑惑
time.Sleep() 真的好嗎?
我們知道這一個語句的作用是讓主goroutine等待,對於一個定時任務來說主goroutine應該一直等待,time.Sleep()肯定不是最好的解決方法,那我們該怎麼做呢
-
勇敢的嘗試
死迴圈
注意一些IDE會提示死迴圈的錯誤,但其實是可以編譯執行的
package main import ( "fmt" "github.com/robfig/cron" ) func main (){ c := cron.New() _ = c.AddFunc("* * * * * *", func() { fmt.Println("hello world") }) c.Start() for { } }
這視乎達到了我們的效果,但是大家都明白這樣做的後果,看下你的電腦cpu利用率,我的電腦cpu佔用率是30%左右
-
利用select改進我們的程式碼
package main import ( "fmt" "github.com/robfig/cron" ) func main (){ c := cron.New() _ = c.AddFunc("* * * * * *", func() { fmt.Println("hello world") }) c.Start() select { } }
現在我的電腦cpu佔用率是10%左右
但這是真的是最好的版本嗎?
-
for 和 select 結合
設定一個定時器
利用for加select等待
每當計時器可以取值時,重置計時器
t := time.NewTimer(time.Second * 10) for { select { case <-t.C: t.Reset(time.Second * 10) } }
* * * * * * 是什麼?
這上面的例子中我們用* * * * * *
來表示我們的定時計劃,我已經告訴你們了,這表示每秒中執行一次,下面讓我們詳細的瞭解一下它的語法吧。
-
這個字串一共由6位組成,每一位之間用一個空格隔開,每一位的意思如下
第一位:秒
第二位:分
第三位:時
第四位:一月中的某天(日)
第五位:月
第六位:星期幾
-
我們明白了位置的含義,那麼這些符號又是什麼意思呢
符號 表示的含義 * 表示 每
的意思,比如在第一位就表示每秒/ 後跟數字表示 每隔
的意思,比如在第一位*/10
,表示每隔10秒執行一次;1-30/10
,表示從第一秒到第30秒每個10秒執行一次, 列舉,比如第6個欄位值是 MON,WED,FRI,表示 星期一、三、五 執行 - 表示範圍,比如第一位 1-30
表示第一秒到第30秒每秒執行一次? 只用於 第四位 和 第六位,表示不指定值,可以用於代替 * 具體的數字 表示具體的時刻,比如第一位是 5
表示第5秒執行
4. 一些常用表示式舉例
含義 | 表示式 |
---|---|
每隔10秒執行一次 | */10 * * * * * |
每個10分鐘執行一次 | 0 */10 * * * * |
每天0點0時0分執行一次 | 0 0 0 * * * |
每天9點18點執行一次 | 0 0 9,18 * * * |
其實cron也給了一些預定義的表示式
預置表示式 | 描述 | 表示式 |
---|---|---|
@yearly (or @annually) | 1 月 1 日午夜執行一次 | 0 0 0 1 1 * |
@monthly | 每個月的午夜,每個月的第一個月執行一次 | 0 0 0 1 * * |
@weekly | 每週一次,週日午夜執行一次 | 0 0 0 * * 0 |
@daily (or @midnight) | 每天午夜執行一次 | 0 0 0 * * * |
@hourly | 每小時執行一次 | 0 0 * * * * |