软件包singleflight提供了一个重复的函数调用抑制机制;
主要作用就是将一组相同的请求合并成一个请求,实际上只会去请求一次,然后对所有的请求返回相同的结果。

type Group
    // Do 执行函数, 对同一个 key 多次调用的时候,在第一次调用没有执行完的时候
    // 只会执行一次 fn 其他的调用会阻塞住等待这次调用返回
    // v, err 是传入的 fn 的返回值
    // shared 表示是否真正执行了 fn 返回的结果,还是返回的共享的结果
    func (g *Group) Do(key string, fn func() (interface{}, error)) (v interface{}, err error, shared bool)

    // DoChan 和 Do 类似,只是 DoChan 返回一个 channel,也就是同步与异步的区别
    func (g *Group) DoChan(key string, fn func() (interface{}, error)) <-chan Result

    // Forget 用于通知 Group 删除某个 key 这样后面继续这个 key 的调用的时候就不会在阻塞等待了
    func (g *Group) Forget(key string)

仅仅是请求参数相同,预期返回结果一致的情况,项目中使用 singleflight 代替 redsync(Redis的分布式互斥锁)

singleflight 和 redsync 逻辑上有一点比较大的区别:

  • singleflight: 将相同key的请求 合并成一个请求,对所有请求返回相同的结果
  • redsync: 只是控制同一时间只允许一个请求执行

举例: 10个请求同时请求,

  • singleflight 只会执行一次 代码逻辑,10个请求接受到相同的执行结果
  • redsync 则是 依次 10次执行代码逻辑,10个请求可能接受到不同的执行结果

redsync 与kmutex

redsync 与 kmutex 逻辑效果基本相同

  • redsync: 使用redis实现,每一个key轮询获取lock,不同的key互不影响
  • kmutex: 使用内置map实现,使用 sync.Cond 唤醒一个协程获取lock,当出现相同的key获取lock等待时,其他不同的key也无法获取lock
0条评论 顺序楼层
请先登录再回复