0.前言
搭建个人博客、网站最头疼的莫过于图片存储的问题了吧,上传到免费图床站点就怕它哪天跑路,利用Github当图床访问速度又慢。
最稳妥的方案还是使用大厂的云存储服务,比如我之前用过的腾讯云COS,只不过也并没有想象中那么美好。。。
它的后台界面极其复杂、难用就不说了。我们使用对象存储首先要考虑的就是防坏蛋盗刷流量,否则,很可能一觉醒来一套房就没了。 (夸张了点)
而腾讯云COS服务没有提供相关防护功能,需要接入腾讯云CDN服务(这是另外收费的),接入腾讯云CDN后,才有抵御攻击以及流量封顶相关配置。再一个就是,接入腾讯云CDN还需要一个国内已备案的域名。总之,对于个人博客、网站来说过于麻烦,也不划算。
1.零成本个人图床方案
后来无意中发现了Cloudflare+Backblaze这套组合搭建图床的方案,完美地符合了我的需求!
Cloudflare免费提供CDN全球加速、以及不计量的DDoS攻击防护,Backblaze云存储前10GB空间免费(用来当个人图床完全够用),需要更大容量的话,它也有着秒杀大厂的实惠价格:
最关键的是Cloudflare和Backblaze都是Bandwidth Alliance(带宽联盟)的成员,它们之间的数据传输(带宽)是免费的,而Cloudflare的CDN服务也不收费,那么这样一来就不用担心流量费用的问题!
没有对比就没有伤害,相比于某些知名大厂,Cloudflare和Backblaze不仅对于平民用户非常友好,最令我感到舒服的更是它们两的后台界面逻辑,非常简洁、直观,一看就懂!
说了这么多,无非就是想表达我对这套方案十分满意,好的产品、服务就应该让更多的人知道!相信你也心动了,接下来搭建教程献上~
2.Backblaze账号注册
打开链接:The Best Unlimited Online Backup and Cloud Storage Services (backblaze.com),进入Backblaze官网
点击B2 Cloud Storage注册账号
进入账号后台页面
3.存储桶创建与上传文件
点击Create a Bucket创建存储桶
设置桶名(建议复杂一点,更安全),选择Public公开,其它选项保持默认
点击Lifecycle Settings
选择只保留最新版本文件—Keep only the last version of the file
点击Upload/Download随便上传一张图片
上传完成后,打开图像查看详细信息
4.Friendly URL
在文件详细信息中,有一个Friendly URL,它就是Backblaze云存储提供的日常引用、访问文件的原始链接,但我们肯定不能使用这个原始链接
由于Backblaze云存储是有每日限额的,如果我们使用原始链接请求,那么是直接从Backblaze请求数据,是会消耗免费额度的:
Daily Storage Caps:日常存储容量前10GB免费
Daily Download Bandwidth Caps:日常下载带宽前1GB免费
Daily Class B Transactions Caps:日常B类事务前2500次免费(B类事务包括下载、获取文件)
Daily Class C Transactions Caps:日常C类事务前2500次免费(C类事务包括创建存储桶、列举存储桶、列举文件版本、列举Keys)
所以如果我们公开的网站上面的图片都是用这种原始链接的话,那么免费额度很快就会被访客用完。而且这个链接不仅暴露了你用的云存储厂商,还暴露了你的桶名,坏蛋直接搞个脚本无限盗刷你的额度,一觉醒来又一套房没了 。。。
这时候就要用到Cloudfare了,将我们自己的域名托管到Cloudfare,使用Cloudfare代理并启用免费的CDN服务,再将域名指向自己的Backblaze云存储地址,这时候使用自己定义的链接请求就是走的Cloudfare而不是Backblaze了。
由于Cloudfare和Backblaze同属带宽联盟成员,它们之间数据传输免费,借由Cloudfare向Backblaze请求数据就不会消耗Backblaze的额度!而且Cloudfare的CDN服务还能够有效提升访问速度。
要开始下面的操作,首先你要有一个自己的域名,建议在国外注册商那里购买,这里推荐我自己最常用的NameSilo:
NameSilo购买域名,免去实名、备案的麻烦 | 晚阳Crown
5.Cloudfare添加CNAME记录
关于Cloudfare如何托管域名,在我之前写的这篇文章中有详细的步骤:
Cloudflare托管域名,免费CDN加速,免费申请有效期15年的证书 | 晚阳Crown
这里就不再赘述了。
将你的域名托管到Cloudfare后,打开DNS>Records,点击Add record添加记录
在Cloudfare中添加一条CNAME记录,做好以下设置后点Save保存:
• 二级域名自定义,这里我设置成img
• Target设置为你的Friendly URL的域名
• 将Proxy status设置为开启,这样就会同时启用Cloudfare代理以及CDN服务
• TTL默认Auto
打开SL/TLS>Overview,将SSL/TLS的加密模式设置为完全(严格)
现在就可以用自定义的域名访问刚才的文件了:
// 原先的:
https://f005.backblazeb2.com/file/oneyangcrown-bucket/avatar.jpg
// 现在的:
https://img.oneyangcrown.top/file/oneyangcrown-bucket/avatar.jpg
6.额度消耗测试
接下来做个简单的测试,对比使用原始链接以及自定义链接请求后,Backblaze云存储额度的消耗情况。
这是bat脚本,使用curl工具来发起请求,url参数为请求链接,iterations参数是请求次数
@echo off
set url=https://f005.backblazeb2.com/file/oneyangcrown-bucket/avatar.jpg
set iterations=50
for /l %%i in (1,1,%iterations%) do (
curl -X GET "%url%"
)
测试结果:可以看到当我使用原始链接请求50次后,流量消耗了5MB,Class B事务增加了50次,而换成自定义链接再次请求50次后,额度消耗几乎没有了:
实不相瞒,我也不清楚为啥还是会有一丁点消耗 ,我预想的应该是零消耗,可能是Backblaze和Cloudfare订好的计费规则吧。
我看带宽联盟的介绍也有说是折扣或免除数据传输费用,这样看来的话,那应该就不是完全免除而是折扣,不过也非常良心了!
7.1 写法一 优化链接
前面我们已经更换了域名,但是链接中还是有存储桶的名称:
https://img.oneyangcrown.top/file/oneyangcrown-bucket/avatar.jpg
暴露存储桶名称是有风险的,如果坏蛋知道你的用的是Backblaze云存储,那么他是能拼凑出你的原始链接的,所以接下来要做的是把链接中的这一段/file/oneyangcrown-bucket去掉,这里用到的是Cloudflare的转换规则。
点击Cloudflare仪表板左侧的Rules>Transform Rules
选择Rewrite URL,点击Create rule创建URL重写规则
填上规则名称(随意,主要用来表明规则的用途),选择Custom filter expression
点击Edit expression
输入not starts_with(http.request.uri.path,"/file/oneyangcrown-bucket")
❗注意:这里第二个参数的值要改成你自己的,还有后面步骤的第一个参数
选择Rewrite to…,选择Dynamic,输入concat("/file/oneyangcrown-bucket",http.request.uri.path)
点击Deploy部署规则
这样规则就启用成功了:
现在就可以用优化好的链接访问刚才的文件了:
// 原先的:
https://img.oneyangcrown.top/file/oneyangcrown-bucket/avatar.jpg
// 优化的:
https://img.oneyangcrown.top/avatar.jpg
7.2 写法二 CF的配置
B2只允许https,并且需要有效证书的验证,你需要检查以下你的CF上的 SSL/TLS –> 概述调成完全严格
你现在需要解析一个CNAME
的域名,例如img.example.com,解析到友好URL的域名上,如果你解析成功你可以试着访问你的域名并带上桶名/以及文件名进行访问。
到这里你应该也许已经明白我们需要后面要配置什么了,我们需要使用CF的 规则–>转换规则—>URi 重写。
我这边提供一下表达式,需要把<>
的内容替换成你自己的包括<>
js
(http.request.uri.path ne "/file/<桶名>" and http.host eq "<你的域名>")
这里提供一些Dynamic的表达式写法
js
concat("/file/<你的桶名>",http.request.uri.path)
经过这样一改,你可以现在尝试以下,不加任何东西直接使用域名+上文件名再试试。
8.优化响应头
在浏览器中打开开发人员工具(默认快捷键是F12),可以看到在请求链接时,响应头有一些X-Bz开头的字段,这些都是和Backblaze云存储相关的,要把它们都隐藏掉。
PS:也可以使用curl工具来获取响应头信息
curl -I https://img.oneyangcrown.top/avatar.jpg
打开Rules>Transform Rules,选择Modify Response Header,点击Create rule创建响应头修改规则
选择All incoming requests,通过点击Set new header来添加一行Header配置,将类型设置为Remove,将所有X-Bz开头的字段添加进去,然后点击Deploy部署规则即可
X-Bz-Content-Sha1
X-Bz-File-Id
X-Bz-File-Name
X-Bz-Info-Src_last_modified_millis
X-Bz-Upload-Timestamp
最后再次测试、查看响应头信息中,规则配置好的字段是否都已移除
9.缓存设置
在前面的额度消耗测试中,之所以使用Cloudfare链接还会有一些消耗,其实是因为缓存控制默认是不缓存的。查看响应头中Cache-Control字段,会发现它的值是max-age=0(资源缓存的有效期限为0,也就是不缓存)。
所以每次通过Cloudfare链接去请求都无法命中CDN缓存,对应的字段就是Cf-Cache-Status的值为MISS,值为HIT才是命中缓存。
这样每次Cloudfare都会直接到Backblaze源服务器去取数据,因为Cloudfare在自己的CDN服务器上找不到缓存数据。
但得益于带宽联盟,借由Cloudfare去向Backblaze取数据,有相应折扣或免除数据传输费用,虽然官方没有明确说明,目前看来就是折扣,所以才会产生一些消耗。
所以,如果开启缓存,那么额度消耗还可以降到更低。
相关文档—Cloudfare CDN默认缓存行为:
Default Cache Behavior · Cloudflare Cache (CDN) docs
点击Bucket Settings
设置Bucket Info为{"cache-control":"max-age=5184000"},5184000秒(也就是60天),最后点Update Bucket保存设置
对于图床数据来说,图片文件不是新增就是删除,一般不会去修改一个图片文件,所以缓存有效期限可以设置更长,没必要让服务器那边频繁更新缓存数据。
查看响应头字段是否已更新过来:
缓存设置完成后,现在再通过Cloudfare链接去测试多次请求同一资源的话,只要CDN服务器上已经缓存了数据,那么后续请求就都是零消耗。
10.兰空图床使用backblaze作为存储策略
实际上兰空图床是支持 backblaze b2 的,只不过 AWS s3 的 sdk 中,默认存在 ACL(https://docs.aws.amazon.com/AmazonS3/latest/userguide/acl-overview.html) 配置,参数值默认为 private,因为 b2 控制台中没有 ACL 设置,使用公开的 bucket 会出现错误:Cannot parse S3 Canned ACL value of 'private'
,所以需要稍微修改点代码,覆盖 acl 配置。
打开文件:
lsky-pro/app/Services/ImageService.php
Line 339 in a8ab0c6
bucket: $configs->get(MinioOption::Bucket),
在 339 行下面追加一行:
options: ['params' => ['ACL' => '']],
示例:
StrategyKey::Minio => new AwsS3V3Adapter(
// ...
bucket: $configs->get(MinioOption::Bucket),
options: ['params' => ['ACL' => '']], // <-- 这里是新增的一行
// ...
),
然后在创建储存策略时,选择 Minio 进行配置即可,以下是配置示例。
其中的 Bucket、连接地址和区域,可以在 b2 控制台创建 Backet 以后找到,AccessKey 和 SecretKey 便是控制台中 App Key 中创建的前面,key ID = AccessKey,applicationKey = Secret Key。
评论区