Golang 神器 singleflight
什麼是 singleflight?
singleflight 是 Go 語言中的一個包,用於抑制對同一資源的重複請求。它確保在同一時間只執行一次對特定資源的操作,而其他並發請求則等待並共享結果。
使用 singleflight 的步驟
- 導入 singleflight 包:
import "golang.org/x/sync/singleflight"
- 創建一個 Group 對象:
var g singleflight.Group
- 使用 Do 方法執行函數:
result, err, _ := g.Do("key", func() (interface{}, error) {
// 執行實際操作
return "result", nil
})
這邊的 key 是用來識別,相同的操作,比如同時間有兩筆 key 都是 "userID1668" ,那會視為同一筆操作。
實際範例
假設我們有一個從數據庫獲取文章的函數:
func getArticle(id int) (string, error) {
// 模擬數據庫查詢
time.Sleep(100 * time.Millisecond)
return fmt.Sprintf("Article %d", id), nil
}
使用 singleflight 改造:
var g singleflight.Group
func getArticleSF(id int) (string, error) {
v, err, _ := g.Do(fmt.Sprintf("article-%d", id), func() (interface{}, error) {
return getArticle(id)
})
if err != nil {
return "", err
}
return v.(string), nil
}
現在即使多個 goroutine 同時調用 getArticleSF 函數,也只會執行一次實際的數據庫查詢。
使用場景
singleflight 主要用於:
- 防止緩存擊穿
- 減少對數據庫的重複查詢
- 合併對同一資源的並發請求
注意事項
- singleflight 只適用於短期的重複抑制,不是長期緩存的替代品
- 需要謹慎設計 key,以確保正確識別"相同數據"的請求
通過使用 singleflight,你可以有效地減少系統負載,提高性能,特別是在高併發場景下。