前言
这是一篇笔记,先记录,自己能看懂,记录下里面核心知识点,有时间再丰富下描述信息,向外界输出。
来个zerolog里面的代码
wr := diode.NewWriter(os.Stdout, 1000, 10*time.Millisecond, func(missed int) {
fmt.Printf("Logger Dropped %d messages", missed)
})
log := zerolog.New(w)
log.Print("test")
高效的原因
zerolog有一段是这么描述diodes API的
Thread-safe, lock-free, non-blocking writer
If your writer might be slow or not thread-safe and you need your log producers to never get slowed down by a slow writer, you can use a diode.Writer as follow:
先看写的地方
直接调用低层多写,单读无锁队列。Write接口里面是往队列里面塞数据。这里还不是真正写的地方
func (dw Writer) Write(p []byte) (n int, err error) {
// p is pooled in zerolog so we can't hold it passed this call, hence the
// copy.
p = append(bufPool.Get().([]byte), p...)
dw.d.Set(diodes.GenericDataType(&p))
return len(p), nil
}
真正写数据的地方
这里从无锁队列里面读取数据,调用真正写的接口。but,只有一个go程。
func (dw Writer) poll() {
defer close(dw.done)
for {
d := dw.d.Next()
if d == nil {
return
}
p := *(*[]byte)(d)
dw.w.Write(p)
// Proper usage of a sync.Pool requires each entry to have approximately
// the same memory cost. To obtain this property when the stored type
// contains a variably-sized buffer, we add a hard limit on the maximum buffer
// to place back in the pool.
//
// See https://golang.org/issue/23199
const maxSize = 1 << 16 // 64KiB
if cap(p) <= maxSize {
bufPool.Put(p[:0])
}
}
}
回答高效的原因
- 使用了无锁队列,没有加锁解锁带来的开销
- 大buffer可以减小go程。超过吞吐量的直接丢了
网友评论