← 返回博客

Cloudflare Workers IP 地理定位:缓存与冷启动

Cloudflare Workers IP 地理定位:缓存与冷启动

Cloudflare Workers 的 IP 地理定位,是指在 Worker 内部读取访客的位置数据,来源可以是内置的 request.cf 对象,也可以是从边缘调用外部 IP 情报 API。这两种方式回答的问题不同,在以它们为基础构建之前,值得先了解各自的缓存和冷启动行为。

Workers 免费提供什么

到达 Worker 的每个请求都带有一个由 Cloudflare 填充的 request.cf 对象。其中包括访客的国家、城市、地区、坐标、时区、ASN 和 AS 组织,以及指明处理请求的数据中心的 colo 字段。CF-IPCountry 标头同样携带国家代码。由于这些数据在你的代码运行之前就已附加,因此不会产生额外的子请求,也不会增加延迟。

它的局限在于范围。request.cf 描述的是当前请求的连接客户端,仅此而已。它无法告诉你出现在日志行、表单字段、webhook 负载或 X-Forwarded-For 链中的 IP 地址的信息,也不携带 VPN、Tor 或滥用标记等信誉信号。一旦你需要丰富任意地址的信息,就要调用 API,缓存决策也由此开始。

在边缘缓存丰富数据

从 Worker 发起的 IP 查询是一个子请求,因此每次未命中缓存的查询都会在请求路径上增加一次网络往返。Cloudflare 提供了几个缓存结果的位置:Cache API(按数据中心,不会全局复制)、KV(全局可读但最终一致,写入需要时间传播),以及在需要单一协调副本时使用的 Durable Objects。它们都不是即插即用的全局缓存,所以请根据你能容忍的程度来选择:对于读密集型查询,Cache API 最简单也最快,而 KV 适合你希望在每个位置都可见的值。

更有价值的设计决策是按字段设置存活时间,因为 IP 情报数据的老化并不均匀。国家和 ASN 的分配变化缓慢,因为地址块的重新分配要经过数月或数年,所以数小时的 TTL 是合理的。信誉标记则不同。ipto 的 VPN、Tor 和滥用情报源每 6 小时刷新一次,其 IP 和 ASN 数据集每天刷新,所以把 is_tor 这样的标记缓存超过几个小时,意味着你提供的答案会比数据源本身还旧。一种实用的划分是:网络事实(asn、asn_org、国家、城市)缓存约一天,标记(is_vpn、is_tor、is_abuser、is_datacenter)缓存时间不超过情报源的刷新间隔。

  • 以规范化后的 IP 作为缓存键(对于 IPv6,如果你的场景是按网络而非按主机,可考虑以 /64 作为键)。
  • 也要缓存否定结果,这样对未列入名单的地址的重复查询就不会每次都访问 API。
  • 切勿不小心将 bogon 结果缓存到公共键下:像 10.0.0.1 这样的私有地址可以在本地直接回答,无需任何 API 调用。

Workers 上的冷启动

Workers 运行在 V8 隔离环境(isolate)中,而不是容器中,因此冷启动通常只需几毫秒,而不是基于容器的函数中常见的数百毫秒。你的代码仍然要为自身的初始化付出代价:庞大的打包体积、对大型查找表的模块级解析,或顶层 await,这些都发生在新隔离环境的第一个请求上。解决办法很平常:保持打包体积小,避免在启动时构建大型内存结构,并且倾向于一次小型 API 调用,而不是把整个地理定位数据库打包进 Worker。

人们在传统 Serverless 中使用的预热 ping 在这里基本上是浪费。隔离环境按 Cloudflare 的调度创建和回收,一次 ping 只能到达一个位置,而冷启动的代价小到缓存查询结果比保持隔离环境存活重要得多。在优化任何东西之前,先用 Workers 分析以及围绕子请求的自定义计时进行测量。

与 ipto 结合使用

一个合理的模式是:对于连接客户端的即时、免费事实使用 request.cf,只在需要更多信息时才调用丰富数据的 API。ipto 的 API 文档展示了 IP 查询响应,它返回国家、城市、ASN、org、currency_code,以及 is_vpn、is_tor、is_abuser、is_datacenter 和 bogon/bogon_type 标记。它免费且无需注册,每天提供 1,000 次免费请求,足以在不涉及密钥管理步骤的情况下为 Worker 做原型。

当查询告诉你该地址属于托管网络时,可以在 ASN 查询中跟进,查看由谁运营以及它宣告了哪些网段。对于被标记的流量,VPN、Tor 和代理检查器会显示 is_vpn 和 is_tor 背后的证据,IP 滥用检查器则显示经交叉印证的评分。请记住,城市级位置是对网络注册或路由所在位置的估计,而不是某人所在的位置,这一局限在为什么城市级准确度有限中有说明。

边缘让查询变快,但并不会让底层数据更精确。请将 request.cf 和任何 API 结果视为同一类证据,按各自变化的速度进行缓存,并让数据源的新鲜程度,而不是边缘的速度,来决定你的 TTL。

直截了当的答案

request.cf 是 Cloudflare 附加到 Worker 中每个请求上的对象。它包括客户端的国家、城市、地区、坐标、时区、ASN 和 AS 组织,以及处理请求的 colo。
不能。request.cf 对象只描述为当前请求建立连接的客户端。要丰富来自日志或负载的任意 IP 地址,请从 Worker 调用 IP 情报 API 并缓存结果。
国家和 ASN 等变化缓慢的网络事实可缓存约一天,VPN、Tor 和滥用等信誉标记的缓存时间则不应超过源情报的刷新间隔。ipto 的威胁情报源每 6 小时刷新一次,IP 和 ASN 数据集每天刷新。
← 返回博客