Go Web服务器高并发优化需协同协程池与连接池:协程池(如ants)限制worker数防雪崩,连接池复用DB/Redis连接,HTTP服务层配置超时与长连接,并通过监控验证效果。

在 Go 中优化 Web 服务器并发,关键不是无限制起 goroutine,而是合理控制资源消耗——协程池管好“处理任务的工人数量”,连接池管好“对外请求的通道复用”。两者配合,才能让高并发既快又稳。
用协程池限制并发处理数,防雪崩
HTTP 处理函数里直接开 goroutine(如 go handleRequest())看似简单,但请求突增时会瞬间创建成千上万个 goroutine,导致内存暴涨、调度开销剧增,甚至 OOM。协程池通过预设 worker 数量,把任务排队交由固定数量的 goroutine 消费。
推荐使用轻量库如 ants:
- 初始化一个带缓冲任务队列的池,例如
pool, _ := ants.NewPool(100),表示最多同时运行 100 个任务 - 在 handler 中提交任务:
pool.Submit(func() { processUserData(req) }),超量任务自动阻塞或返回错误(可配拒绝策略) - 避免在池中做阻塞操作(如未设 timeout 的 HTTP 调用),否则 worker 被占住,池就失效
用数据库/Redis 连接池复用底层连接
每次请求都新建 DB 或 Redis 连接,会快速耗尽文件描述符,也增加 TCP 握手和认证开销。Go 标准库的 database/sql 和主流 Redis 客户端(如 redis-go)默认已内置连接池,只需正确配置参数:
立即学习“go语言免费学习笔记(深入)”;
-
db.SetMaxOpenConns(50):控制最大打开连接数(不是并发数,是连接句柄上限) -
db.SetMaxIdleConns(20):保持空闲连接数,减少频繁建连 -
db.SetConnMaxLifetime(30 * time.Minute):定期换旧连接,防长连接僵死 - Redis 客户端同理,设置
PoolSize、MinIdleConns等字段
注意:连接对象(*sql.DB 或 *redis.Client)应全局复用,不要每个 handler 新建。
HTTP 服务层本身也要调优
协程池和连接池再好,若 HTTP 服务器没配对,也会成为瓶颈:
- 用
http.Server显式启动,别只用http.ListenAndServe() - 设置
ReadTimeout/WriteTimeout防慢连接占着不放 - 启用
SetKeepAlivesEnabled(true)(默认开启),复用 TCP 连接 - 必要时调整 OS 层参数:增大
net.core.somaxconn和文件描述符限制
监控与验证是否真有效
优化不是调完参数就结束。要验证效果:
- 用
runtime.NumGoroutine()观察峰值 goroutine 数是否可控 - 查
database/sql的DB.Stats(),看Idle、InUse、WaitCount是否合理(WaitCount 持续上涨说明连接不够) - 用
ab或hey压测对比 QPS、P99 延迟、内存增长曲线 - 接入 pprof,分析 CPU 占用热点和 goroutine block profile
不复杂但容易忽略。










