浅聊池化技术(一)| 青训营笔记

70 阅读2分钟

这是我参与「第五届青训营 」伴学笔记创作活动的第 4 天

池化技术

池化技术能够减少资源对象的创建次数,提⾼程序的响应性能,特别是在⾼并发下这种提⾼更加明显。使用池化技术缓存的资源对象有如下共同特点:

  1. 对象创建时间长
  2. 对象创建需要大量资源
  3. 对象创建后可被重复使用

池化分类

常见的池化场景有以下几种:

  • 协程(线程)池
  • 连接池
  • 内存池
  • 对象池

协程池

协程池是一种资源管理技术,它可以控制并发协程的数量,避免因过多协程而导致的系统负载过高的问题。在使用协程池时,程序会预先创建一定数量的协程,并将其加入到一个协程池中。当需要执行某个任务时,从协程池中获取一个空闲的协程,执行任务完成后再将协程放回协程池中,等待下一次使用。

协程池通常用于并发量较大的场景,例如高并发的 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 不会自动限制任务的数量,所以在使用时需要根据具体情况设置任务的最大数量,以避免内存泄漏和性能下降问题。