很多个人站长的网站都跑在一台两核两G的小服务器上,配置不高,磁盘不大,带宽更是按兆算。网站运行一两年之后,文章里的图片越来越多,服务器开始出现各种"亚健康"症状:磁盘剩余空间越来越少,备份包越来越大,高峰期访客一多带宽就被图片占满,网页打开变得很慢。其实,图片这种"重"资源,本来就不应该和网站程序挤在同一台小服务器上,把它交给专业的对象存储服务,才是个人站长最划算的做法。本文就来完整讲一遍对象存储图床的搭建思路、选型对比和实际操作。
一、为什么要把图片从服务器里搬出去
先算一笔简单的账。假设一篇图文教程里有十张截图,每张经过压缩后平均两百KB,那么一篇文章就是两MB左右的图片。日更或者隔日更的站点,一年下来图片体积轻轻松松涨到几百MB甚至上G。这些图片挤占的是你最宝贵的系统盘空间,而且每次做全量备份,图片都会让备份体积和备份时间成倍增加。
第二个问题出在带宽上。个人服务器的带宽通常只有三到五兆,而一个页面里图片请求往往占掉六七成以上的流量。一旦某篇文章被推荐或者被搜索引擎带了一波流量,几十个人同时打开页面,带宽瞬间被打满,结果是图片加载不出来,连文字内容也跟着变慢,用户体验和搜索引擎对网站的评价都会受影响。把图片挪到对象存储之后,图片请求走的是对象存储和CDN的边缘节点,不占用源站带宽,源站只需要专心处理页面请求,网站的整体速度和稳定性都会有明显提升。
第三个好处是安全和省心。图片单独存放之后,即使服务器被入侵或者磁盘损坏,图片数据也安然无恙;网站搬家、换服务器的时候,也不用再拖着一大包图片数据来回迁移,服务器上只剩下程序、数据库和必要的配置,整个运维负担会轻很多。
二、主流对象存储方案怎么选
市面上主流的对象存储服务不少,国内用户接触最多的是阿里云OSS、腾讯云COS和七牛云Kodo,海外服务里最有名的则是Cloudflare R2和Backblaze B2。它们的基本能力都一样:把文件以"桶"为单位存放,通过HTTP地址直接访问。真正的差别在于免费额度、流量计费方式、国内访问速度和是否需要备案域名。
阿里云OSS和腾讯云COS功能最全、国内访问快,但下行流量费按G收费,图片站流量一大费用就很可观,而且绑定自定义域名做HTTPS要求域名已经完成ICP备案。七牛云同样需要备案域名,优点是存储和CDN一体,使用方便。Cloudflare R2最大的卖点是出站流量免费,存储免费额度是十GB,个人博客的图片量基本用不完,缺点是免费套餐的节点都在海外,国内访客直接访问速度一般,适合访客以海外为主或者套了国内CDN回源的场景。Backblaze B2同样提供十GB免费存储,并且和Cloudflare有带宽联盟合作,从B2回源到Cloudflare不产生流量费,是海外站的经典省钱组合。
给个人站长的选型建议很简单:访客主要在国内,选腾讯云COS或者阿里云OSS加CDN,域名记得先备案;访客在海外或者做外贸站,直接上Cloudflare R2或者B2加Cloudflare,几乎零成本。如果只是想给文章配图、不追求极致速度,也可以先用手头的免费额度跑起来,等流量大了再升级。另外要注意,选型时别只盯着存储单价,一定要把流量费、请求费算进去,图片这种读多写少的资源,流量费才是长期的大头。
三、以 Cloudflare R2 为例从零搭建
下面以Cloudflare R2为例走一遍完整流程,其他家的操作路径大同小异,照着菜单找对应功能即可。
第一步,注册并登录Cloudflare控制台,在左侧菜单找到R2,首次使用会提示创建存储桶,桶名称建议用图片相关的英文名,比如img-bucket或者blog-images,区域可以选亚太地区,离国内近一些。第二步,在桶的"设置"里找到公开访问相关选项,把桶设为公开读,这样图片才能通过URL直接访问。注意只开读权限,千万不要开公共写。第三步,绑定自定义域名。在R2的"自定义域名"里添加你的图片域名,比如img.example.com,前提是这个域名已经托管在Cloudflare,添加后Cloudflare会自动为它签发HTTPS证书,整个过程不需要你手动上传任何证书文件。
第四步,创建API令牌用于上传工具连接。在R2的"管理API令牌"里新建一个令牌,权限选择"对象读写",创建后页面会显示Access Key ID和Secret Access Key,Secret只显示一次,一定要先保存好。到这里,一个图床的骨架就搭好了,接下来要考虑的是怎么把图片传上去。
四、上传工具:图形界面与命令行两手准备
日常零星上传图片,推荐用PicGo这类图形工具。PicGo本身支持各种插件,装一个S3兼容协议的插件,把上面拿到的Access Key、Secret Key、桶名和S3端点地址填进去,以后在编辑器里截图,拖进PicGo就能自动上传并把外链地址复制到剪贴板,写文章贴图非常顺手。
如果你要迁移整站的历史图片,或者想让服务器上的图片定期自动同步上去,就需要命令行工具rclone。rclone是开源的多云同步工具,对S3兼容协议支持很完善,配置文件中关键内容大致如下:
[r2]
type = s3
provider = Cloudflare
access_key_id = 你的AccessKeyID
secret_access_key = 你的SecretAccessKey
endpoint = https://你的账户ID.r2.cloudflarestorage.com
region = auto配置完成后,一条命令就能把服务器上的上传目录整体同步到桶里:
rclone sync /var/www/html/wp-content/uploads r2:img-bucket/uploads --progressrclone的sync是增量同步,第一次全量上传,之后每次只传新增和变化的文件,配合crontab定时任务,就能实现"服务器上的新图片自动进图床"。
五、程序接入:让新图片自动进图床
如果希望以后上传的图片直接就进对象存储、不占服务器磁盘,就需要在网站程序里做接入。WordPress生态很成熟,装一个支持对象存储的媒体库插件,比如阿里云OSS、腾讯云COS都有官方或第三方插件,配置好密钥和桶信息后,后台上传图片时会自动传到远端,本地不再保留原图。Typecho用户则可以找对应的上传驱动插件,把默认的本地存储替换成对象存储。
这里给一个务实的提醒:如果不想折腾插件,或者担心插件兼容性,完全可以用"半自动"方案,也就是图片仍然先传本地,靠rclone定时同步到图床,再把文章里的图片地址批量换成图床地址。这种方式改动最小、风险最低,对个人博客来说完全够用。
六、存量图片迁移实战
历史文章里的图片要迁移,最稳妥的流程分三步。第一步,先用rclone把服务器上的图片目录完整同步到桶里,并抽样访问几个图片URL确认能正常打开。第二步,把数据库中文章内容的图片域名批量替换成图床域名,WordPress的替换语句大致如下:
UPDATE wp_posts SET post_content = REPLACE(post_content,'https://www.example.com/wp-content/uploads',
'https://img.example.com') WHERE post_content LIKE '%wp-content/uploads%';
第三步,替换完成后在网站前台随机打开几篇老文章,确认图片都能正常显示。这里特别提醒一句:SQL替换只建议针对文章内容表,千万不要对options这类可能存有序列化数据的表做无脑REPLACE,序列化数据里字符串长度是预先算好的,直接替换URL会导致数据损坏。另外,本地图片文件建议保留一两个月再清理,作为回退方案,万一CDN缓存有问题还能随时切回去。
七、安全与避坑清单
图床虽然只是放图片,安全上一样不能马虎,下面几条都是真实踩过的坑:
一是权限。桶保持公开读、私密写即可,所有上传操作都通过最小权限的API令牌完成,一旦令牌泄露,要第一时间在控制台吊销重建。二是指防盗链。如果担心图片被别的网站直接引用,可以在对象存储的防盗链设置里配置Referer白名单,只允许自己的域名引用。不过要注意很多浏览器和下载工具直接访问图片时不带Referer,白名单太严会把正常访问也挡掉,建议对空Referer放行。三是费用保护。对象存储的计费包含请求次数,如果图片链接被人恶意刷量,请求费会快速上涨,务必在控制台开通费用预警,必要时给CDN设置流量封顶。四是开启版本控制和生命周期规则,防止误删文件,同时让超过一定时间的临时文件自动清理。五是国内合规,国内云厂商的存储绑定自定义域名必须备案,没备案的域名会被拦截,这一点在选型阶段就要想清楚。
八、常见问题
问:图床的图片被搜索引擎收录会受影响吗?答:不会,图片放在独立子域名上反而更有利于图片搜索,只要在站长平台把图片域名添加为站点并提交sitemap即可。
问:服务器上的图片删除后,图床里也要手动删吗?答:rclone sync以本地为准,本地删掉的文件同步时远端也会删除,如果不想删远端,用copy代替sync即可。
问:国内访问R2太慢怎么办?答:可以在R2前面再套一层国内CDN做回源,或者干脆换用腾讯云COS这类国内存储,速度才是国内访客体验的第一位。
把图片从服务器上解放出来,是个人网站迈向"轻源站"的第一步。存储交给专业厂商,带宽留给页面内容,网站能跑得更快,维护起来也更轻松,值得每个图片多的站长认真做一次。