本文结合业务经历,记录了如何降低静态资源流量成本的方法。有很多东西真的只有在业务实战中才会去仔细思考,最佳实践大多也都是一次次尝试出来的。
通常我们会用 OSS 去存储应用的静态资源,例如图片、视频、音频等。但是 OSS 在下载这些资源时,价格往往较高,以阿里 OSS 为例,其下行流量价格是 147元/100G。
CDN 网络,它能将资源缓存到不同地区的服务器中,用户在返回时会请求最近的服务器,访问速度大大提高。同时,其下行流量的价格还更加便宜,仅需 14元/100G。
使用 OSS + CDN 的方案,我们只需支付 CDN 的下行流量费用,和少部分 OSS 的回源流量费用。
GPT4 配图:能看但不是特别准确:
在使用 CDN 时,我们通常会为资源设置一个缓存过期时间,对于不常更新的资源可以设置一个较长的时间。
但是这个缓存时间只是对于 CDN 服务器有效的,也就是说客户端每次请求还是会消耗下行流量资源。
这时,我们可以设置一个自定义响应头,其参数为 Cache-Control,有了这个响应头可以对资源快速响应,甚至无需经过服务器,直接从硬盘读取客户端数据。
参数值可以有如下的配置:
参数值 | 说明 |
---|---|
public | 所有内容都将被缓存 |
private | 内容只缓存到私有缓存中 |
no-cache | 必须先与服务器确认返回的响应是否被更改,然后才能使用该响应来满足后续对同一个网址的请求 |
no-store | 所有内容都不会被缓存到缓存或 Internet 临时文件中 |
must-revalidation/proxy-revalidation | 如果缓存的内容失效,请求必须发送到服务器/代理以进行重新验证 |
max-age=xxx | 缓存的内容将在 xxx 秒后失效 |
将 Cache-Control 也设置一个较长的时间。
看下配置了缓存头后的效果,在有 Cache-Control 响应头加持的情况下,它会将资源被标记为 disk cache,也就是说它从硬盘直接读取了这个图片,而没有通过网络请求,速度上也会比从网页请求的速度要快很多。
为了防止恶意流量的盗刷,不过这也只能防君子,可以配个 Refer 源白名单,比如应用只是提供给微信小程序使用的,那可以加如下配置。
上面的这些都是在 CDN 层面进行降本的方法。到 OSS 中还可以增加对图片压缩处理,以到达降低流量的效果。
实测降低质量到原图的 70% 左右,肉眼是很难区分的,但如果拉升图片宽高,拉升到原来的50-70%,那对图片质量的损失还是比较明显的。所以在配置时可以经可能的配置降低图片质量,而不去动图片大小。
大部分时候我们上传的图片格式是 png 或 jpg 等,我们可以试着封装图片格式,png 的大小通常会比 jpg 大,不过在阿里云 OSS 中,可以将其修改为 webp 格式。webp 格式是谷歌研发的一种图片编码格式,同等的图片质量下,比上述的 png 和 jpg 的大小都会小。但是它不支持一些很老的浏览器,不过好在也用不到。
计算了一下,图片从 jpg 到 webp 后,节省了大小 (29548-
21612) / 29548 = 26.86%,平均图片体积基本都小了 20%。
在一些电商场景中,首页的商品列表图片通常会小一些,而进入详情页后的图片才会比较大。之前我在不同场景下用的是同一个图片尺寸,这就导致了流量开销非常大。
可以分别为缩略图和详情图设置不同的图片样式格式,并且缩略图一般都是正方形,那可以将其大小直接固定。图片处理后按要求的格式进行访问即可,建议是自定义一个访问规则。
这一系列操作下来,最终 CDN 的日均下行流量从 20 G 降至日均 2G,节省了约 90% 的成本!
学习了,顺便收藏下,以备不时之需