Go 的定時器

weixin_33866037發表於2017-09-12

這個東西其實早就應該總結一下了,然而一直懶=_=,順便事情很多,就一直沒有總結。為什麼需要做一個定時器呢,假設我們現在有個服務,服務過程中需要從 redis 中讀取快取資料,如果快取資料不存在那麼我們讀線上資料庫,讀取完畢之後寫入 redis 作為熱資料。這個過程中,如果是同步的,很明顯,讀寫快取的操作是不應該阻塞主要服務的,這時候我們就需要自己做個定時器來做超時機制,防止因為快取服務的問題而影響主要服務(當然,做成非同步是OK的)。

Code Here

// author by @xiaoyusilen

package main

import (
    "fmt"
    "time"
)

func loop() int {

    for i := 0; i < 100; i++ {
        fmt.Println(i)
    }

    return 0
}

func main() {
    ticker := time.Timer(time.Microsecond * 1) // 新建一個定時器,設定超時時間,這裡設定的是1微秒
    ch := make(chan *int, 1) // 設定一個 chan 接收服務返回值
    go loop() // 起一個 goroutine 執行服務

    select {
    case <-ch: // 如果收到服務返回值,則說明未超時
        ticker.Stop() // 停止計時器
        return
    case <-ticker.C: // 如果先收到定時器的訊號,則說明超時了
        fmt.Println("timeout") // 這裡做超時處理
        return
    }
}

這裡寫的非常簡易~可以根據需要自行更改,至於用time.Timer更好還是time.Ticker更好,取決於實際情況,這兩個最大的區別在於,time.Ticker不能呼叫time.After()方法,而且time.Ticker.Stop()呼叫了stopTimer的方法。這裡的超時時間定為1微秒了,為了測試方便並且造成超時的情況,具體的超時時間根據業務需求來決定,通常超時時間不能超過主要服務的平均響應時間。

測試結果如下,可以看到還沒有輸出完畢就超時了。

0
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
timeout

好咯,一個簡單的定時器就這樣完成了~

FYI

godoc-tick

godoc-time/sleep

相關文章