背景
很多 Go 服务都会做 worker pool,但只做“固定 worker 数量”还不够。
真正决定稳定性的,是池子打满后怎么办。
基础模型
type Job func(context.Context) error
type Pool struct {
jobs chan Job
}
func NewPool(workerN, queueN int) *Pool {
p := &Pool{jobs: make(chan Job, queueN)}
for i := 0; i < workerN; i++ {
go func() {
for job := range p.jobs {
_ = job(context.Background())
}
}()
}
return p
}
关键点:拒绝策略
func (p *Pool) TrySubmit(job Job) error {
select {
case p.jobs <- job:
return nil
default:
return errors.New("worker pool saturated")
}
}
当队列已满时,快速失败通常比无限排队更可控。
总结
worker pool 的目标不是“永不拒绝”,而是让系统在高峰时有可预测行为。
配合监控和限流,才能构成完整保护链路。
可用系统的关键是边界清晰,而不是无限扛压。