这是我参与「第五届青训营 」伴学笔记创作活动的第 4 天
池化技术
池化技术能够减少资源对象的创建次数,提⾼程序的响应性能,特别是在⾼并发下这种提⾼更加明显。使用池化技术缓存的资源对象有如下共同特点:
- 对象创建时间长
- 对象创建需要大量资源
- 对象创建后可被重复使用
池化分类
常见的池化场景有以下几种:
- 协程(线程)池
- 连接池
- 内存池
- 对象池
协程池
协程池是一种资源管理技术,它可以控制并发协程的数量,避免因过多协程而导致的系统负载过高的问题。在使用协程池时,程序会预先创建一定数量的协程,并将其加入到一个协程池中。当需要执行某个任务时,从协程池中获取一个空闲的协程,执行任务完成后再将协程放回协程池中,等待下一次使用。
协程池通常用于并发量较大的场景,例如高并发的 Web 服务器、网络爬虫等。在 Go 语言中,有许多第三方库提供了更高级的协程池实现,例如 ants、go-pool 等。
ants 简单使用
package main
import (
"fmt"
"github.com/panjf2000/ants/v2"
"sync"
)
func main() {
const numJobs = 10
var wg sync.WaitGroup
pool, _ := ants.NewPool(3)
for j := 1; j <= numJobs; j++ {
wg.Add(1)
pool.Submit(func() {
fmt.Printf("Worker processing job %d\n", j)
wg.Done()
})
}
wg.Wait()
pool.Release()
}
在这个示例中,我们首先创建了一个 ants 协程池,通过 ants.NewPool() 方法创建,其中 3 表示协程池中协程的数量。然后,我们使用 ants.Submit() 方法将任务提交到协程池中,Submit() 方法会自动分配空闲的协程来执行任务,不需要手动创建协程。在 Submit() 方法的参数中,我们传递了一个函数,该函数表示具体的任务操作。在这个示例中,我们只是简单地输出了任务编号。最后调用 pool.Release() 方法来释放协程池中的协程。
ants 还提供了一些额外的功能,例如协程池中协程的增加、减少、重启等操作。此外,它还提供了协程池的自定义配置选项,例如设置协程池的大小、协程池中每个协程的工作函数、协程池中协程的最大空闲时间等。
需要注意的是,ants 在默认情况下使用的是 GOMAXPROCS 个数的协程池,即每个 CPU 核心对应一个协程池。在某些情况下,可能需要调整 ants 的协程池大小以获得更好的性能。另外,ants 不会自动限制任务的数量,所以在使用时需要根据具体情况设置任务的最大数量,以避免内存泄漏和性能下降问题。