0

0

如何在Golang中实现一个并发图片下载器 Go语言协程池下载实战

P粉602998670

P粉602998670

发布时间:2026-03-11 13:50:31

|

688人浏览过

|

来源于php中文网

原创

应使用带缓冲的channel控制并发数,如sem := make(chan struct{}, 10),每次下载前

如何在golang中实现一个并发图片下载器 go语言协程池下载实战

goroutine 泄漏导致内存爆满怎么办

不加限制地起 go downloadImage(url),几万张图下来进程直接 OOM。根本原因不是下载慢,是没等下载完协程就挂了,但 HTTP 连接、响应体缓冲、甚至未回收的 http.Client 实例还在占内存。

  • 必须用带缓冲的 channel 控制并发数,比如 sem := make(chan struct{}, 10),每次下载前 sem ,结束后 <code>
  • 别复用全局 http.Client 时忽略 TimeoutTransport.MaxIdleConnsPerHost,否则 DNS 缓存+连接池会悄悄吃光句柄
  • context.WithTimeout(ctx, 30*time.Second) 包裹每个请求,防止某张图卡死拖垮整个池

文件名冲突和路径安全怎么处理

直接用 URL 的 path.Base() 当文件名,遇到 https://i.example.com/1?w=800&h=600 就生成 1?w=800&h=600,Linux 下创建失败,Windows 直接报错 invalid argument

  • url.Parse() 解析后取 u.Path,再用 path.Base(u.Path);接着用 strings.TrimSuffix() 去掉查询参数干扰
  • 对结果做一次 filepath.Clean() 防止 ../ 路径穿越,再用正则替换非法字符:re := regexp.MustCompile(`[:"/\|?*]`)re.ReplaceAllString(name, "_")
  • 保存前先 os.MkdirAll(dir, 0755),别假设目录一定存在

下载失败后如何重试又不阻塞池子

单次失败就 return,会导致任务丢失;全量重试又可能把超时请求反复塞进池子,压垮目标站或自己。

蛙蛙写作——超级AI智能写作助手
蛙蛙写作——超级AI智能写作助手

蛙蛙写作辅助AI写文,帮助获取创意灵感,提供拆书、小说转剧本、视频生成等功能,是一款功能全面的AI智能写作工具。

下载
  • 每张图最多重试 2 次,用 for i := 0; i 包裹核心逻辑,成功就 <code>break
  • 每次重试前加 time.Sleep(time.Second (即 1s、2s、4s),避免雪崩式重试
  • 失败日志里必须打上原始 urlerr.Error(),否则排查时根本不知道哪张图卡在哪一步
  • 别在重试逻辑里直接 go download(...) —— 协程池已负责调度,重复起 goroutine 就破防了

为什么用 io.Copy 而不是 io.ReadAll

io.ReadAll(resp.Body) 会把整张图读进内存再写文件,10MB 的图 × 10 并发 = 至少 100MB 内存常驻;而大图下载场景下,内存占用比 CPU 更早成为瓶颈。

立即学习go语言免费学习笔记(深入)”;

  • 直接 io.Copy(f, resp.Body),数据流式写入磁盘,内存峰值只取决于 OS page cache 大小
  • 记得在 io.Copy 前设好 f.Sync() 或用 os.O_SYNC 标志(视可靠性要求而定),否则断电可能丢最后几 KB
  • 如果要校验 MD5/SHA256,用 io.TeeReader(resp.Body, hashWriter),边读边算,不额外加载

事情说清了就结束。真正难的不是起十个协程,是让它们在出错、超时、路径异常、磁盘满、对方限速时,依然不泄漏、不卡死、不污染输出目录。

热门AI工具

更多
DeepSeek
DeepSeek

幻方量化公司旗下的开源大模型平台

豆包大模型
豆包大模型

字节跳动自主研发的一系列大型语言模型

通义千问
通义千问

阿里巴巴推出的全能AI助手

腾讯元宝
腾讯元宝

腾讯混元平台推出的AI助手

文心一言
文心一言

文心一言是百度开发的AI聊天机器人,通过对话可以生成各种形式的内容。

讯飞写作
讯飞写作

基于讯飞星火大模型的AI写作工具,可以快速生成新闻稿件、品宣文案、工作总结、心得体会等各种文文稿

即梦AI
即梦AI

一站式AI创作平台,免费AI图片和视频生成。

ChatGPT
ChatGPT

最最强大的AI聊天机器人程序,ChatGPT不单是聊天机器人,还能进行撰写邮件、视频脚本、文案、翻译、代码等任务。

相关专题

更多
golang如何定义变量
golang如何定义变量

golang定义变量的方法:1、声明变量并赋予初始值“var age int =值”;2、声明变量但不赋初始值“var age int”;3、使用短变量声明“age :=值”等等。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

210

2024.02.23

golang有哪些数据转换方法
golang有哪些数据转换方法

golang数据转换方法:1、类型转换操作符;2、类型断言;3、字符串和数字之间的转换;4、JSON序列化和反序列化;5、使用标准库进行数据转换;6、使用第三方库进行数据转换;7、自定义数据转换函数。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

247

2024.02.23

golang常用库有哪些
golang常用库有哪些

golang常用库有:1、标准库;2、字符串处理库;3、网络库;4、加密库;5、压缩库;6、xml和json解析库;7、日期和时间库;8、数据库操作库;9、文件操作库;10、图像处理库。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

356

2024.02.23

golang和python的区别是什么
golang和python的区别是什么

golang和python的区别是:1、golang是一种编译型语言,而python是一种解释型语言;2、golang天生支持并发编程,而python对并发与并行的支持相对较弱等等。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

214

2024.03.05

golang是免费的吗
golang是免费的吗

golang是免费的。golang是google开发的一种静态强类型、编译型、并发型,并具有垃圾回收功能的开源编程语言,采用bsd开源协议。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

409

2024.05.21

golang结构体相关大全
golang结构体相关大全

本专题整合了golang结构体相关大全,想了解更多内容,请阅读专题下面的文章。

490

2025.06.09

golang相关判断方法
golang相关判断方法

本专题整合了golang相关判断方法,想了解更详细的相关内容,请阅读下面的文章。

200

2025.06.10

golang数组使用方法
golang数组使用方法

本专题整合了golang数组用法,想了解更多的相关内容,请阅读专题下面的文章。

1438

2025.06.17

C# ASP.NET Core微服务架构与API网关实践
C# ASP.NET Core微服务架构与API网关实践

本专题围绕 C# 在现代后端架构中的微服务实践展开,系统讲解基于 ASP.NET Core 构建可扩展服务体系的核心方法。内容涵盖服务拆分策略、RESTful API 设计、服务间通信、API 网关统一入口管理以及服务治理机制。通过真实项目案例,帮助开发者掌握构建高可用微服务系统的关键技术,提高系统的可扩展性与维护效率。

3

2026.03.11

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
Go 教程
Go 教程

共32课时 | 6.1万人学习

Go语言实战之 GraphQL
Go语言实战之 GraphQL

共10课时 | 0.9万人学习

关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号 技术交流群
PHP中文网订阅号
每天精选资源文章推送

Copyright 2014-2026 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号