spencerwooo / substats

( `д′) how many followers do i have? how many!
https://substats.swo.moe
MIT License
813 stars 56 forks source link

feat: introduce cache layer #27

Closed chawyehsu closed 3 years ago

chawyehsu commented 3 years ago

Resolve #23

substats 目前缺乏缓存机制,用户端每一次访问的返回,都是 worker 实时向上游各个服务/接口请求处理后再下发。导致存在 https://github.com/spencerwooo/Substats/issues/23#issuecomment-731524402 提及的问题。

怪不得每次都得等“半分钟”😂,source 越多越久。缓存也可以减少对上游服务的请求频次,降低被封禁风险。

Cloudflare Workers 引入缓存机制的话,涉及到三层缓存,由下往上分别是 Fetch API 层,Edge CDN 层以及 Browser 层。

Browser 层就是设置在用户端浏览器进行缓存,这是最末端一层,这一层缓存受控能力弱,用户”一不小心“进行 F5 强刷就能逃逸。使用这一层缓存的效果不大,所以为了简化逻辑,我禁用了 Browser 层缓存。

最下层的 Fetch API 层缓存,使用得当的话,理论上能对每一个上游服务/接口的请求进行细粒度的缓存控制。但是 Cloudflare Workers Fetch API 层缓存用得爽需要氪金。所以这层我只显示地告诉 Cloudflare 去尝试缓存所有 Fetch 请求,但不作保证。

所谓 Edge CDN 层,指利用 Cloudflare 提供的 Cache API,手动告诉各边缘节点按照给定的设置,缓存 worker 本身下发的响应。这一层不能像 Fetch API 层那样做每一个上游服务粒度的缓存控制(因为是根据请求 URL 做缓存,所以 /?source=github&queryKey=spencerwooo/?source=github&queryKey=spencerwooo&source=sspai&queryKey=spencerwoo 会被视作两个缓存项,这里下层就不会对 github 接口请求做缓存),但是对比 Browser 层相对可控,使用 F5 不可逃逸。考虑到 substats 本身在接口数据更新方面可能比较敏感,所以我只对每一个实际的 substats API 请求设置了 5 分钟的缓存时长(可视情况调整,感觉 30 分钟感知度应该也不会太大)。一定程度上还是能缓解 https://github.com/spencerwooo/Substats/issues/23 的问题。

发起 substats API 请求后,观察响应头中的 CF-Cache-Status 可判断缓存是否生效。

vercel[bot] commented 3 years ago

This pull request is being automatically deployed with Vercel (learn more).
To see the status of your deployment, click below or on the icon next to each commit.

🔍 Inspect: https://vercel.com/spencerwoo/substats/8k1vudy14
✅ Preview: https://substats-git-feature-cache.spencerwoo.vercel.app