1) 用 context
控制超时与级联取消
在微服务/CLI 中,优雅地中止 I/O 比“粗暴退出”更重要。Go 的 context
能级联取消:父取消,子必然结束;并且可附带超时/截止时间。下例展示 HTTP 调用在超时后立刻停止,且 goroutine 无泄漏。
package main
import (
"context"
"net/http"
"time"
)
func main() {
ctx, cancel := context.WithTimeout(context.Background(), 800*time.Millisecond)
defer cancel()
req, _ := http.NewRequestWithContext(ctx, "GET", "https://example.com", nil)
cli := &http.Client{}
if _, err := cli.Do(req); err != nil {
// 超时或上游错误;在此收敛日志与指标
}
}
要点:1)只把 ctx
作为第一个参数向下传;2)不要把 context
存结构体;3)资源型 goroutine 内部 select { case <-ctx.Done(): ... }
;4)服务端也用 http.Server{ ReadHeaderTimeout:..., IdleTimeout:... }
配合超时策略,避免慢客户端拖垮连接池。