📌Golang📌常用包📌x-sync.txt
"golang.org/x/sync"是"sync"标准库的官方扩展包。
singleflight提供了重复函数调用抑制机制,多用于热点数据并发控制,防止缓存击穿。
errgroup为处理一组goroutine提供同步、错误传播和上下文取消,多用于耗时IO请求的并发控制。
========== ========== ========== ========== ==========
import "golang.org/x/sync/singleflight"
var single = &singleflight.Group{} //函数外全局声明,通常注入到依赖receiver结构中
func GetServerToken(ctx context.Context) (string, error) {
//Do方法第一个参数必须唯一,可使用数据唯一标识或者函数方法名保证唯一性
val, err, _ := single.Do("GetServerToken", func() (any, error) {
//同一时间同一实例只会发起一个请求,其余请求等待返回结果共享
return dao.GetServerToken(ctx)
})
return val.(string), err //结果需断言
}
========== ========== ========== ========== ==========
import "golang.org/x/sync/errgroup"
//如需发起多个http请求获取结果,可以通过errgroup将串行改成并发,并在出现任一失败时退出所有协程
func MultiRequestCount(ctx context.Context, keys []string) (int64, error) {
//单纯的计数使用原子值保存累加结果,不应使用chan(浪费资源,使用不当还可能造成阻塞)
total := &atomic.Int64{}
g, c := errgroup.WithContext(ctx)
for _, val := range keys {
addr := val //version<1.22必须赋值到局部变量,否则迭代完成才开启协程,所有协程都会处理迭代最后一项。
g.Go(func() error {
count, err := apiCount(c, addr) //这里应使用errgroup返回的context
if err != nil {
return err
}
total.Add(count)
return nil
})
}
if err := g.Wait(); err != nil {
return 0, err
}
return total.Load(), nil
}