1. 程式人生 > 實用技巧 >golang 實現定時任務 cron

golang 實現定時任務 cron

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 * * * *