尧图网络 高端网站定制 · 原创设计
免费咨询热线
400-888-6620
免费获取方案
(1/26)GO练习题-Goroutinue泄漏
某电商公司的订单服务上线后运行了大约 2 小时OOMOut of Memory被 K8s 杀死进程反复重启。运维同事看到的日志只有一行fatal error: runtime: out of memory。开发同事重启了几次问题依旧。直到有经验的架构师用 pprof 看了一眼 goroutine 分布才发现每处理一个请求就 leak 一个 goroutine而且这些 goroutine 全部卡在 channel 的 send 操作上永远无法退出。1000 个 QPS × 2 小时 720 万次泄露的 goroutine每个 goroutine 默认 2KB 栈空间再加上分配的堆对象最终把内存吃光了。教训goroutine 泄露是 Go 生产环境中最隐蔽、危害最大的并发问题之一。没有之一。学习目标理解 goroutine 的生命周期谁启动、谁负责停止理解 channel 阻塞如何导致 goroutine 泄露掌握 context.WithCancel 的正确用法和取消传播链学会用 net/http/pprof 检测 goroutine 泄露问题描述下面的代码是一个模拟的请求处理函数。每个请求启动一个 worker goroutine 来处理任务并将结果发送到 channel。但这段代码有一个 goroutine 泄露——worker goroutine 在完成工作后试图向 resultCh 发送结果时如果没有人读取就会永远阻塞。请找出泄露点并修复它。原始代码有 BUGpackage mainimport (“fmt”“math/rand”“time”)func simulateRequest() {resultCh : make(chan string) // 无缓冲// 启动 worker goroutine 处理请求 go func() { // 模拟耗时处理300~800ms time.Sleep(time.Duration(rand.Intn(500)300) * time.Millisecond) resultCh - fmt.Sprintf(处理完成耗时 %dms, 300rand.Intn(500)) // TODO: 这里会泄露——如果 resultCh 没人读goroutine 永远卡住 }() // TODO: 模拟请求取消或超时的情况比如 500ms 后调用方不再关心结果 // 如果 worker 还没完成它就 leak 了 time.Sleep(500 * time.Millisecond) // 这里不会收到结果因为 goroutine 已经被阻塞在 send 上了 fmt.Println(请求方放弃等待)}func main() {for i : 0; i 5; i {simulateRequest()fmt.Printf(“第 %d 个请求处理完毕\n\n”, i1)time.Sleep(200 * time.Millisecond)}fmt.Println(“所有请求处理完毕”)// 运行后观察goroutine 数量只增不减time.Sleep(2 * time.Second)}预期现象运行后 goroutine 数量持续增长因为这些 goroutine 卡在 resultCh - … 上无法退出。修复要求使用 context.WithCancel 修复泄露问题确保worker goroutine 能感知到取消信号及时退出使用 defer cancel() 确保清理修复后运行goroutine 数量保持稳定面试追问Q1: 如何用 pprof 检测 goroutine 泄露答// 在 HTTP 服务中启用 pprofimport _ “net/http/pprof”然后通过以下命令检查查看 goroutine 数量curl http://localhost:6060/debug/pprof/goroutine?debug1导出 goroutine profile 到文件curl http://localhost:6060/debug/pprof/goroutine -o goroutine.prof用 pprof 工具分析go tool pprof goroutine.prof生产环境中定期采集 goroutine 数量并设置告警是必要的。Q2: channel 阻塞的 4 种情况场景 谁阻塞 是否泄露1 sendCh - val无人接收 发送方 是发送方 goroutine 永久阻塞2 -recvCh无人发送 接收方 是接收方 goroutine 永久阻塞3 双向 channel两端都关闭后继续读写 读写方 是panic 或永久阻塞4 select 中没有 default 分支所有 case 都阻塞 select 所在 goroutine 是goroutine 永久阻塞Q3: 如何用 context 预防 goroutine 泄露答核心原则——所有从请求衍生出的 goroutine都应该传入同一个 context并在 context 取消时优雅退出。func handler(ctx context.Context) {ctx, cancel : context.WithCancel(ctx)defer cancel() // 关键无论什么路径退出都调用 cancelgo func() { defer fmt.Println(goroutine 已退出) select { case -ctx.Done(): return // context 取消优雅退出 case resultCh - doWork(): // 发送成功正常退出 return } }() // ... 处理逻辑}context 取消传播链用户请求取消 / 超时→ handler 的 context 被 cancel→ 所有通过 context.WithCancel/WithTimeout 衍生出的子 context 被 cancel→ 所有 select 中 case -ctx.Done() 分支触发→ 所有衍生 goroutine 退出
RELATED

相关推荐

XAI不是加解释模块,而是重构AI交付全流程

XAI不是加解释模块,而是重构AI交付全流程

1. 这不是给算法看的说明书,而是给业务方、监管者和用户写的“信任契约”ExplainableAI(XAI)这个词,这两年在技术会议、合规文档和产品评审会上出现的频率,已经高到让一线工程师听到就想默默关掉会议通知。但绝大多数人…

📅 2026/8/3 20:25:40
4G、WiFi 6、蓝牙 5.3 物联网选型指南:5 大关键指标与 3 个典型场景

4G、WiFi 6、蓝牙 5.3 物联网选型指南:5 大关键指标与 3 个典型场景

4G、WiFi 6、蓝牙5.3物联网选型实战:5维参数与3大场景深度解析当智能家居的温控器每隔30秒上传一次环境数据,当工业传感器在电磁干扰严重的车间传输振动信号,当运动手环需要同时处理心率监测和音乐播放——这些场景背后,是开发者对…

📅 2026/8/5 8:00:55
torchvision数据集及DataLoader的使用

torchvision数据集及DataLoader的使用

本文主要介绍torchvision内置数据集及DataLoader使用 文章目录一、CIFAR10 数据集初识(举例)1.一句话理解2.CIFAR10 数据档案3.数据集下载二、查看数据集内容1.基本操作2.数据结构三、与 transforms 联动四、DataLoader — 从"一副牌"到"…

📅 2026/7/16 2:50:34
MORE NEWS

更多资讯

📰

GPU Aspect-Based架构解析:专用计算单元设计

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

📰

深度解读 ClickHouse v22.7.4.16-stable 变更日志:哈希计算、ALTER 重算索引、DNS 解析等 5 个关键缺陷修复

深度解读 ClickHouse v22.7.4.16-stable 变更日志:哈希计算、ALTER 重算索引、DNS 解析等 5 个关键缺陷修复 【免费下载链接】ClickHouse ClickHouse is a real-time analytics database management system 项目地址: https://gitcode.com/GitHub_Trending/cli/Cl…

📰

项目管理中的双轨风险分析法:定性与定量结合实践

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

📰

定制线缆组件:智能设备信号完整性与可靠性的物理层基石

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

📰

2岁小模型:轻量Transformer实现儿童级语言理解

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

📰

二自由度机械臂欧拉-拉格朗日建模与MATLAB仿真验证

简介:针对二自由度机械臂的逆动力学分析需求,一套MATLAB源码包给出了欧拉-拉格朗日动力学模型的完整实现,适合机器人控制、机械工程及自动化相关专业学生与研究人员学习和二次开发。代码以关节位置、速度、加速度为输入,利用拉格朗…

TODAY

今日更新

THIS WEEK

本周精选

THIS MONTH

本月热门

读完文章,想聊聊您的网站?

告诉我们您的行业与需求,资深顾问一对一梳理方案与报价,全程免费。

📞 💬