这两天博客的访问一直处于一个时好时坏的状态,最大的问题就是图片加载速度极为不稳定。目前博客的图片存储方案是 CloudFlare R2 + Webp Cloud ,R2 负责存储图片,Webp Cloud 负责压缩图片和保护 R2 储存桶地址。问题就出在 Webp Cloud 的访问速度上,由于 服务器高悬美西,在链路质量较差的情况下很难得到一个良好的访问速度。

这大概是海外博客站点都需要面对的情况,跨境数据传输无论如何都没有办法做到成本和质量的平衡,作为一个独立小站只能尽力去优化(截止本文发出,本站只被 Google 收录, 所以貌似也没人能在国内网络下搜到吧 😂)。况且本站除了首页封面图外(这张是自己拍的)大部分图片都是在 Unsplash 下载的,在访问的时候直接加载原图那体验必然是爆炸的,后端的图片处理这时候就成为了必要且关键的一环。

本文想要谈的是,在 Webp Cloud 服务质量不理想的情况下,通过自托管 Webp server 来达到国内对本站的尽可能的访问加速。

在云服务器上部署服务

本次操作在一台位于香港的机器上进行。

Webp Cloud 服务本身是基于开源的 Webp Server Go 搭建的,现在逐渐作为这一项目的上游。Web Server Go 提供了非常方便的 Docker 镜像,可以一键搭建和启动服务,具体的文档见这里

1
2
3
4
5
$ docker run --restart=always -d -p 3333:3333 \
-v ~/WebpServer/config.json:/etc/config.json \
-v ~/WebpServer/pics:/opt/pics \
-v ~/WebpServer/exhaust:/opt/exhaust \
--name webp-server webpsh/webp-server-go:master

在容器跑起来后,可以通过如下指令检测服务器状态:

1
$ curl  localhost:3333/healthz

如果服务器成功启动,则会看到如下输出:

1
WebP Server Go up and running!🥳#  

将远程请求代理到本地端口

容器启动后服务就在后台运行了,但是这个时候只是运行在本地端口上,要向外部提供服务,则需要将外部请求代理到本地的 3333 端口上。

这里可以使用 Caddy 作为反代服务器,写一个很简单的配置文件,这里需要去 Caddy 官方的打包站下载包含对应域名服务商插件的二进制版本,提替换本地包管理器安装的可执行文件,这里我用的是 Cloudflare 的 DNS服务

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
(tls_site) {
tls {
dns cloudflare YourCloudflareDnsAPIKeyReplaceHere
}
}

you.domain.here {

import tls_site
encode {
zstd
gzip
}
handle /* {
reverse_proxy localhost:3333 {
header_up Accept-Encoding identity
header_up Host {upstream_hostport}
}
}
}

执行如下指令启动 Caddy, 那么就可以实现将访问本地 3333 端口的 WebpServer 服务了

1
caddy start --config /path/to/Caddyfile

但是这还是不能满足我们的需求,我们通过 https://you.domain.here/path/to/image.png 访问服务器,服务器会找不到这张图片,因为我们的图片是存在远程 Cloudflare R2 储存桶中的,所以我们还要通过配置文件配置远程图片服务器地址,让 Webp Server能够访问到原始图片

简单的配置文件如下,写到对应的 config.json 中

1
2
3
4
5
6
7
8
9
10
{
"HOST": "0.0.0.0",
"PORT": "3333",
"QUALITY": "70",
"IMG_PATH": "这里写远程服务器地址",
"EXHAUST_PATH": "./exhaust",
"ALLOWED_TYPES": ["jpg","png","jpeg","bmp","gif","svg","heic"],
"MAX_CACHE_SIZE": 1,
"CACHE_TTL": 259200
}

注意!!!!
如果 config.json 不是一个合法的json文件, Webp Server会自动使用默认配置, 不会有任何提示(开发者在Issue中提到会针对这点进行修正), 配置文件不会产生任何效果, 请一定确保 json 文件合法!

尾声

这一套流程耗费了不少的时间,个人部署的 Webp Server能否得到一个良好的体验,关键在服务器的性能和宽带线路。这又是一个成本,精力和便捷性不可能三角,在跑通上述流程后,我会将自托管的 Webp Server当做备用方案,以便在 Webp Cloud 体验无法接受的情况下作为应急解决办法,两个方案的手动切换也处于一个可控的状态。在博客访问质量的问题上,之后不会也不应该投入太多的时间了,It’s futile 😞