首页
学习
活动
专区
圈层
工具
发布

Go 接口不加 Context,会发生多可怕的事

你有没有遇到过这种情况:

用户早就把页面关了,

你的服务器却还在疯狂跑 SQL。

CPU 90%,goroutine 堵死,

数据库连接池被占满,

你一边查日志,一边怀疑人生:

“人都走了,服务怎么还在干活?”

这类 Bug,比你想象中更危险

我见过一次真实事故:

一个导出接口,没有任何超时控制。

用户点了导出,

发现数据太大,

直接关闭页面走人。

但服务器这边:

一条 SQL,跑了10 分钟

接着又有 10 个用户点导出:

• 数据库连接池耗尽

• 正常请求全部变慢

• 服务直接雪崩

这些请求没有业务价值

却在消耗最贵的资源。

不设超时、不支持取消,本质上就是给系统埋雷。

根本原因

你的代码大概率是这样的:

func GenerateReport() {

  // 不管用户还在不在,我都要跑完

  for i := 0; i < 10; i++ {

      time.Sleep(1 * time.Second)

      fmt.Println("Processing part", i)

  }

  fmt.Println("Report complete")

}

他的问题只有一个:只要被调用,就必须跑完

服务器在干什么?

在为一个已经离开的用户拼命工作。

Context 是什么?

你可以把context当成:

一根可以随时拉闸的电线。

它能告诉函数三件事:

• ⏰ 超时时间

• 取消信号

• 请求范围内的值

你可以理解为:

上游一旦说“停”,

下游所有函数都必须停。

这个“停”,可能来自:

• 用户关了浏览器

• 超时了

• 程序主动取消

改造只需要一步

func GenerateReport(ctx context.Context) {

  for i := 0; i < 10; i++ {

      select {

      case <-ctx.Done():

          return

      default:

      }

      time.Sleep(time.Second)

      fmt.Println("Processing", i)

  }

}

核心就一句:

在干活前,先看看有没有人叫你停。

从 HTTP 请求天然支持 Context

func HandleReport(w http.ResponseWriter, r *http.Request) {

  ctx := r.Context() // 用户关闭页面会自动 cancel

  GenerateReport(ctx)

}

现在流程变成:

用户关页面

Context 取消

goroutine 退出

资源释放

我亲自测了一下:

请求跑到一半关闭页面,

后面的逻辑根本不会执行

⏱️ 还不够:必须加「超时保护」

但只靠用户行为是不够的。

如果:

• 用户一直开着页面

• SQL 卡死

• 程序逻辑异常

你的服务还是会被拖死。

所以要加这一层保险:

func HandleReport(w http.ResponseWriter, r *http.Request) {

  ctx, cancel := context.WithTimeout(r.Context(), 5*time.Second)

  defer cancel()

  GenerateReport(ctx)

}

这段代码的含义是:

不管用户走没走,

5 秒后我强制拉闸。

这是服务器给自己的“保险丝”。

一个90%的人都会踩的坑:忘记 cancel()

这一句非常重要:

defer cancel()

很多人会问:超时不是会自动 cancel 吗?

是的,但问题是:WithTimeout 内部会创建定时器。

如果你的函数提前返回:

• ⏳ 定时器还在

• 🧠 资源还没释放

• 内存会慢慢积累

忘了 cancel = 定时器泄露。

这是非常隐蔽的一种内存泄漏,

线上才会慢慢暴露。

🧭 避坑清单(建议收藏)

Context 永远作为第一个参数

不要把 Context 存进 struct

WithTimeout 一定要defer cancel()

用select监听ctx.Done()

用ctx.Err()打日志区分原因

🧨 总结一句话

服务器最怕的不是慢,

而是为“已经走掉的用户”拼命干活。

用了 Context:

• 用户走了 停

• 超时到了 停

• 系统保护 停

你写的每一行代码,

都应该知道:

什么时候该继续,什么时候该停。

你线上项目里,用 Context 了吗?

有没有遇到过:

• 用户早走

• 服务还在跑

• 数据库被拖死

的情况?

评论区聊聊你的真实经历。

  • 发表于:
  • 原文链接https://page.om.qq.com/page/O9mRiOgFbXbLGCYYLkNDbGPw0
  • 腾讯「腾讯云开发者社区」是腾讯内容开放平台帐号(企鹅号)传播渠道之一,根据《腾讯内容开放平台服务协议》转载发布内容。
  • 如有侵权,请联系 cloudcommunity@tencent.com 删除。
领券