Web系统架构 Golang Lamp Nginx MySQL
参考文章
知识点
- Pool只是一个缓存,一个缓存,一个缓存。由于生命周期受GC的影响,一定不要用于数据库连接池这类的应用场景,它只是一个缓存。
- golang1.13版本对Pool进行了优化,结构体添加了两个字段 victim 和 victimSize。
- 适应于通过复用,降低复杂对象的创建和GC代价的场景
- 因为init()的时候会注册一个PoolCleanup函数,他会在gc时清除掉sync.Pool中的所有的缓存的对象。所以每个sync.Pool的生命周期为两次GC中间时段才有效,可以手动进行gc操作 runtime.GC()
- 由于要保证协程安全,所以会有锁的开销
- 每个Pool都有一个私有池(协程安全)和共享池(协程不安全),其中私有池只有存放一个值。
1. 每次Get()时会先从当前P的私有池private中获取(类似MPG模型中的G)
2. 如果获取失败,再从当前P的共享池share中获取
3. 如果仍失败,则从其它P中共享池中拿一个,需要加锁保证协程安全
4. 如果还失败,则表示所有P中的池(也有可能只是共享池)都为空,则需要New()一个并直接返回(此时不会被放入池中)
每次取值出来后,会从原来存储的地方将该值删除。