Go Context 超时、取消与请求链路控制
wxk1991 Lv5

Go Context 超时、取消与请求链路控制

context.Context 是 Go 后端开发里非常重要的工具。它可以在请求链路中传递取消信号、超时时间和少量请求级数据。


一、为什么需要 Context

假设一个 HTTP 请求触发了数据库查询、远程 API 调用和后台计算。如果用户已经断开连接,这些任务继续运行就是浪费资源。Context 可以把“请求已取消”的信号传下去。


二、设置超时

1
2
ctx, cancel := context.WithTimeout(context.Background(), 3*time.Second)
defer cancel()

defer cancel() 很重要,它会释放内部资源。


三、监听取消

1
2
3
4
5
6
select {
case <-time.After(5 * time.Second):
fmt.Println("done")
case <-ctx.Done():
fmt.Println(ctx.Err())
}

当超时或主动取消时,ctx.Done() 会收到信号。


四、在函数间传递

Go 项目中,约定通常是把 ctx 作为第一个参数:

1
2
3
func QueryUser(ctx context.Context, id int64) error {
return nil
}

这样调用链上的每一层都可以响应取消。


五、不要滥用 Value

context.WithValue 只适合传递请求级元数据,比如 trace id、用户 id。不要把数据库连接、配置对象、大型业务参数塞进 context。


六、实践建议

服务端代码里,外部 IO 基本都应该接受 context:数据库、HTTP 客户端、RPC 调用、队列消费。这样服务在超时、重启、客户端断开时才能优雅收尾。