沉舟侧畔千帆过
病树前头万木春
前言
某日闲来无事,翻看几年前写下的旧文,却惊觉满屏皆是碎裂的图标——博客里数百张配图,不知何时尽数失效。那些当年精心截下的架构图、代码片段、笔记草图,如今只剩一个个无法加载的裂痕,像记忆里被虫蛀空的洞。
我的图床,塌了。
本文记录这次从废墟里抢救近五百张配图、并将它们安置到 Azure Blob 的全过程。
一、废墟勘察
动手之前,先要弄清损失几何。博客由 Jekyll 驱动,所有文章都是 _posts/ 下的 Markdown,于是一行 grep 便可清点全部图片来源:
grep -rhoE 'https?://[^)" ]+' _posts | grep -oE 'https?://[^/]+' | sort | uniq -c | sort -rn
结果触目惊心:
| 数量 | 图床 |
|---|---|
| 373 | http://45.32.68.50 |
| 58 | http://upload-images.jianshu.io |
| 40 | http://gavinmandias.online |
| 8 | *.sinaimg.cn |
| 余下 | IBM / 百度 / DockOne / GitHub 等零散外链 |
45.32.68.50 是我早年租的一台 Vultr 小鸡,gavinmandias.online 是绑在它上面的域名——两者相加 413 张,是绝对主力。可惜这台机器早已欠费销毁,如今只剩一个无人应答的 IP。
用 curl 逐一验尸,判决书一目了然:
[000] http://45.32.68.50/large/xxx.jpg # 连接超时,服务器已死
[000] http://gavinmandias.online/large/xxx.jpg # 同上
[403] https://tva1.sinaimg.cn/large/xxx.jpg # 微博 CDN 尚在,但防盗链
[200] http://upload-images.jianshu.io/xxx.jpg # 简书还活着
二、抽丝剥茧
转机出现在我盯着那些文件名发呆的时候——006tNbRwly1g9wb6xprryj30em05ujs8.jpg,这分明是微博图床的哈希命名。原来当年那台小鸡不过是个反向代理:图其实一直存在微博的 sinaimg.cn 上,我只是借它绕开防盗链罢了。
那么,只要能重新绕过微博的防盗链,图就还在。微博防盗链靠的是 Referer 校验,于是我把请求伪装成从微博站内发出:
# 直接请求:403
curl -I https://wx1.sinaimg.cn/large/006tNbRwly1fyleppxqtij30g30ib790.jpg
# 带上微博的 Referer:200!
curl -e "https://weibo.com/" \
https://wx1.sinaimg.cn/large/006tNbRwly1fyleppxqtij30g30ib790.jpg
[200] 100912 bytes——那一刻,几百张以为永远丢失的图,忽然又触手可及。
三、备份归来
正当我准备写脚本从微博批量回捞时,翻箱倒柜竟找到了当年的本地备份:~/Documents/Images/large,静静躺着 416 张原图。既然有原件,自然不必再劳烦微博。
于是写了个脚本,对博客里引用的每一张图,优先从本地备份取,取不到再联网回捞(微博的走 Referer 绕过,简书的直接下载)。核心逻辑不过几行:
# 1) 本地备份优先
if [ -s "$BACKUP/$fname" ]; then
cp "$BACKUP/$fname" "$out"
# 2) 死掉的自建图床 / 微博 -> 走 Referer 绕过
elif [[ "$host" == *sinaimg.cn || "$host" == 45.32.68.50 ]]; then
curl -fsSL -e "https://weibo.com/" -o "$out" "https://wx1.sinaimg.cn/large/$fname"
# 3) 其余(简书等)-> 直接下载
else
curl -fsSL -o "$out" "$url"
fi
跑完一核对,账算得很清楚:
- 485 张引用图(去重)
- 411 张备份命中 ✅
- 58 张简书 + 8 张微博直链,联网补齐 ✅
- 2 张”下载成功”的其实是百度防盗链吐回的 HTML 假图,用
file --mime-type一眼识破,剔除 - 最终 478 张真图归位
剩下 7 张彻底失联的,是当年从 IBM、DockOne、GitHub、百度图搜随手外链的示意图——别人的东西,早已人去楼空。这也算一记教训:外链他人图床,终究是空中楼阁。
四、云端安家
有了图,接下来是找个靠谱的新家。这次不再自建小鸡,直接托付给 Azure Blob Storage——省心、稳定,日后还能挂 CDN。
五、一键换血
最后一步,是把散落在几十篇文章里的旧链接,统一换成新地址。我没有用正则一把梭,而是让”下载阶段”就记录下 旧 URL → 文件名 的映射,改写时只动确认迁移成功的那些,第三方死链原样保留,绝不误伤。
一个几十行的 Python 脚本,先空跑预览,确认无误再落地:
回车落下,477 处引用尽数复原,满屏裂痕一朝抚平。
结语
一次图床崩塌,牵出一串旧账:
- 自建图床是把双刃剑:省钱灵活,但机器一旦销毁,数据便随风而去。本地备份,务必勤做。
- 防盗链并非绝境:
Referer伪装虽是旁门左道,却解了燃眉之急;只是依赖他人 CDN 终非长久之计。 - 外链他人图片是原罪:那 7 张再也回不来的图提醒我,图床这种事,还得攥在自己手里。
如今图片安睡在云端,但愿这一次,能陪这些文字走得更久一些。
沉舟已过,万木逢春。