做了个小站,匿名扔一个瓶子(自己最近在看的几条视频、在玩的游戏),再捞一个陌生人的上来。上线不到三周,海里现在 234 个瓶子。说几个卡了挺久的工程问题,产品本身放最后。
一、KV 的免费额度,坑在写和 list 上
Cloudflare Workers KV 的免费额度是每天 10 万次读,看着很宽,但写只有 1000 次,list 也只有 1000 次。我原来的写法是每次捞瓶都 list 一遍索引再 put 更新被捞计数,开首页也 list ,结果几百次访问就收到了 50% 用量告警。
改了两处。瓶子索引放 isolate 内存里缓存 60 秒,扔瓶时主动失效,保证新瓶马上能被捞到。被捞计数改成抽样写,1/10 的概率写一次、每次记 10 ,总量上无偏,但单个瓶子的数字变成了估算值,这点在后台标了出来。两条加起来,写和 list 降到原来的十分之一左右。
二、同样是取元数据,三个站三种结局
瓶子里要显示标题、作者、封面,得去各家取。
YouTube 最省事,oEmbed 端点服务端直接调就行。
B 站是硬钉子。api.bilibili.com 对 Cloudflare Workers 的机房 IP 是整段封的,返回 -412 ,换 UA 、换 Referer 、换接口( view / stat / pagelist )全都没用。最后走的是扔瓶人自己的浏览器:view 接口带 jsonp=jsonp&callback= 用 script 标签请求,script 不发 Origin 所以不触发 403 ,带着外站 Referer 反而放行。服务端只做 ID 格式校验和封面域名白名单清洗。另外 B 站封面挂在别的域名下要加 referrerpolicy=no-referrer ,不然一片防盗链。
Steam 本来以为是第二个 B 站。store.steampowered.com/api/appdetails 对 IP 限流,大概 200 次 5 分钟,Workers 又是共享出口。上线前先部署了个一次性探针实测:16 次里 13 次直接绿,返回 200 和正确的 name ,延迟 180 到 350 毫秒;剩下 3 次是 Cloudflare 自己的 error 1042 ,全集中在 worker 刚部署后那几分钟,而且都发生在串行连打 20 个的那版探针上,改成一次打 3 到 10 个就再没出现过。Steam 那边一次 429 和 403 都没返回。
所以 Steam 走服务端验证,取不到再自动回落到浏览器给的元数据。局限也说清楚:只测到 HKG 一个 colo ,别的机房出口有没有被限流,没测过。
瓶子里的条目本来就是异构的,YouTube 带 vid 、B 站带 bvid ,加游戏就是第三种,带 appid ,按字段判平台。所以视频和游戏能混在同一个瓶子里,捞的时候不做分类。
三、一个还没解决的
捞到视频点开就能看,捞到游戏当下什么也做不了。几十块钱加几十个小时的决定,「捞一下」这个动作承载不住。现在游戏卡片只放封面、名字和「 TA 在玩」,点了跳 Steam ,不带购买和愿望单按钮。这只是没帮倒忙,问题本身没解决,暂时想不出好办法。
站在 https://b.bking.film ,不用注册,代码在 https://github.com/bkingfilm/bk-bottle