golang.org/x/sync/singleflight 是 Go 语言的一个包
其主要用于解决 “多个相同请求并发查询,只需要一个请求去查询,其他的等待查询结果即可” 的问题
以此来减少不必要的重复操作,节省资源
比如有很多线程同时发出了相同的请求(使用了相同的键)
此时如果对每一个请求都做处理可能会浪费资源,使用 singleflight 包可以保证在同一时刻,对于相同的请求,只有一个真正的查询操作
var sg singleflight.Group
func main() {
var wg sync.WaitGroup
// 模拟10个并发请求
for i := 0; i < 10; i++ {
wg.Add(1)
go func() {
defer wg.Done()
v, err, _ := sg.Do("database_query", func() (interface{}, error) {
// 这里模拟一个耗时的数据库查询操作,只会被请求一次
fmt.Println("database query start")
time.Sleep(2 * time.Second)
fmt.Println("database query done")
return "query result", nil
})
if err != nil {
fmt.Println(err)
return
}
fmt.Println("request done, result: ", v)
}()
}
wg.Wait()
}
在上述代码中,无论 Do 函数被调用多少次
只要 key 没有变,真正执行的操作 func 只会被执行一次
其余的调用都会等待这一次的结果
在返回值中,v 和 err 是操作 func 的返回结果
shared 是一个布尔值,表示这个结果是否被多个调用共享