☰
Cloudflare OS:用边缘组件构建统一站点基础设施的实践
2026/10/28 20:05:15 网站建设 项目流程

这个项目名挺有意思的,cloudflare-os,一眼看上去像是个要搞操作系统的项目。其实不是,我把它理解成一套基于 Cloudflare 技术栈搭建的“站点操作系统”——把所有网站基础设施相关的功能,包括网络入口、域名解析、边缘计算、数据存储、安全防护、缓存加速,全部塞进同一个平台来统一管理。如果你自己维护过几个网站、折腾过服务器、盯过攻击日志,应该能立刻理解我在说什么:传统方式里,DNS 在阿里云,CDN 在又拍云,图床在七牛,WAF 在另一家,你得像操作员一样切换七八个控制台,还要处理各家的计费规则和 API 差异。而 cloudflare-os 的思路就是把这些散落的“硬件资源”集中到一个 Cloudflare 账号里,像操作系统调度 CPU、内存、磁盘那样统一编排。这套做法的核心价值不是“用了 Cloudflare”,而是通过一个可复用的结构和一套自动化配置,把 CDN、Worker、KV、R2、WAF 这些组件组合成一个能跑在边缘上的完整应用底座。这篇文章我会把这套底座的设计逻辑、落地步骤、核心配置、以及我从实际部署里踩出来的坑,全部拆开来讲,适合正在折腾个人站、独立开发小应用、或者想给团队做一套轻量基础设施的读者参考。

1. 整体设计:为什么把 Cloudflare 当“操作系统”来用

1.1 一个控制台管全部,省掉的不只是切换成本

先还原一下背景。我这个项目最早的需求特别朴素:一个个人博客、一个文档站、两个小 API,加一台家里淘汰下来的小主机拿来跑批处理任务。这些东西如果按传统思路部署,需要域名托管服务、CDN 服务、对象存储、边缘函数、安全防护,至少三四家服务商来回切。而我那段时间正好在做一些边缘计算的实验,越用越发现 Cloudflare 的组件像积木一样能拼起来:DNS 管入口,CDN 管加速,WAF 管安全,Worker 管逻辑,KV/R2 管数据,Pages 管前端托管。于是我就把它当成一个完整的系统来做,把账号当作“内核”,把各个功能模块当作“设备驱动”,最终得到一个只用 Cloudflare 面板和一套 API 就能运维全部站点的环境。

关键是要理解这个“操作系统”和传统服务器架构的本质区别。传统架构里,CDN 只是个缓存加速层,源站仍承担大量计算和存储工作;而 cloudflare-os 模式下,Workers 承担业务逻辑,KV/R2 承担持久化,源站甚至可以被弱化到只剩一个静态文件服务或者干脆不存在。这就引出下一个问题:这套设计并不是为了让 Cloudflare “更好用”,而是为了把运维模型从“物理服务器思维”切换成“边缘原生思维”。

1.2 五个子系统,对应操作系统的五个模块

我梳理下来,一个完整的 cloudflare-os 至少要拆成下面几个逻辑模块:

子系统对标 OS 组件核心 Cloudflare 产品职责
流量调度层系统总线 / 中断控制器DNS + CDN + Rulesets接管所有请求入口,决定流量往哪走
计算层进程调度器Workers / Pages Functions执行业务逻辑,动态生成响应
存储层文件系统 / 数据库KV、R2、D1保存配置、文件、结构化数据
安全层内核安全模块WAF、速率限制、SSL/TLS拦截恶意请求,保证链路加密
治理层注册表 / 系统日志Cloudflare API、Terraform Provider统一配置、日志分析、自动化运维

这样说可能有点抽象,我举个例子:一个用户请求访问你的站点,DNS 解析先把他带到一个就近的边缘节点,这叫“流量调度”;CDN 命中缓存就直接返回,没命中就交给 Worker 处理,这叫“计算”;Worker 要从数据库拿数据,这里用的是 KV 或者 D1,这叫“存储”;整个过程中的恶意特征由 WAF 在请求进入 Worker 之前就完成过滤,这叫“安全”;而你所有的配置变更都通过 Terraform 管理,等于把整个系统的状态“声明”在代码里,这叫“治理”。这套结构跑顺之后,任何新增的站点或服务都变成一次声明式配置,而不是从头搭一遍环境。

1.3 这套思路适合谁,不适合谁

作为一个从传统 LNMP 环境摸爬滚打过来的人,我必须先泼一盆冷水:cloudflare-os 并不是万能方案。它适合的是个人站长、独立开发者、小团队,这些场景的特点是流量波动大、没有专职运维、不想为多套系统付维护成本。它特别适合博客、文档站、撮合类小 API、定时任务、首页聚合这类轻业务。但如果你在做高并发低延迟的交易系统、需要大量服务端渲染且强依赖会话状态、或者业务里有复杂的关系型查询,那 Worker 的 10 毫秒 CPU 限制和 KV 的最终一致性会把你折磨到怀疑人生。还有一点很现实:Cloudflare 的边缘节点遍布全球,如果你大部分用户都在国内,访问速度受网络环境影响波动较大,这一点要提前评估,不要看了一堆夸 Cloudflare 的英文文章就上头。

2. 入口层落地:DNS 接管与流量调度规则

2.1 域名迁移的第一件事:盘点记录,别直接照搬

接入 cloudflare-os 的第一步是把域名 NS 记录切到 Cloudflare。听起来就是改两个 NS 地址的事,但我的建议是先做记录盘点。很多运营过一段时间的域名,DNS 里什么妖魔鬼怪都有:过期项目的 A 记录、指向旧服务器的 CNAME、为了验证某些服务加的 TXT 记录,甚至还有已经失效的 MX。我见过有人迁移后发现邮件从某一天开始收不到,就是漏掉了一条 MX 记录。

操作顺序是:先在原服务商导出所有记录,按类型分组,逐条标注用途;然后只在 Cloudflare 里重建仍然有效的记录;最后再切 NS。特别注意那些用于证书验证的 CNAME 和 TXT 记录,像 _acme-challenge 这种,如果你用的是自动续期的证书,迁移后要重新确认验证链路是否通了,不然证书到期会发现续不上。

2.2 橙色云和灰色云,不是随手点着玩的

Cloudflare DNS 面板里每条记录有个“代理状态”开关,业内常叫橙色云/灰色云。这个选择的本质是:这个记录要不要经过 Cloudflare 的边缘节点。我见过太多人把所有记录一股脑开橙云,结果源站的 API、WebSocket 全被打出来各种奇奇怪怪的连接问题。我的经验法则是:

记录类型建议状态原因
网站主域名、www橙色云需要 CDN 加速和 WAF 防护
API 子域名橙色云(视场景)可享受缓存和速率限制,但长连接注意超时
邮件 MX 记录灰色云邮件流量不应该绕经 CDN
直接连接源站的部署记录灰色云避免无限回源循环
需要公开真实 IP 的服务灰色云这类场景就别指望隐藏源站了

开橙色云之后,源站会收到来自 Cloudflare IP 段的请求,所以源站防火墙、安全组需要把 Cloudflare 官网公布的回源 IP 段加白,千万别开成“仅允许 Cloudflare 访问”之后忘了把自己的调试 IP 也加白,不然你 SSH 上去排查问题的时候会发现自己也被挡在外面,这种低级错误我犯过。

2.3 用 Rulesets 做流量调度,精细控制每一类请求

DNS 层面的控制是粗粒度的,真正的流量调度是在 Rulesets 里做的。Cloudflare 把原来分散在 Page Rules、Firewall Rules、Transform Rules 里的一部分能力整合成了 Rulesets,统一在一个“规则集”入口里管理。我常用的几个场景如下。

第一类,按国家/地区调度。你的源站如果部署在某个区域,那么其他区域的用户访问就直接给静态缓存,或者引导到镜像源。可以用自定义规则里设置地区条件,然后执行“区块”或“跳过缓存”动作。第二类,按路径匹配调度。比如 /api/ 路径走 Worker 处理且不缓存,/static/ 路径强制走缓存且设置较长的 TTL。用 Rulesets 写这种配置的体验很接近写防火墙规则,条件之间是 AND 关系,可以组合路径、方法、Header、来源 IP。

一个具体的自定义规则示例:让 /api/ 下的 POST 请求直接进入 Worker,同时把 /static/ 下的资源缓存 30 天。在 Rulesets 里我一般这样配:

  • 规则名:api-no-cache,匹配 hostname 包含 api.example.com,动作:使用 Worker 处理,并禁用缓存
  • 规则名:static-long-cache,匹配 URI 路径以 /static/ 开头,动作:设置缓存 TTL 为 2592000 秒

这里有个容易被忽视的细节:Rulesets 的执行顺序影响最终结果。规则是按列表顺序从上到下匹配的,第一条命中了后面的就不执行了。所以更具体的路径规则、带认证的接口规则要放在前面,通用的、兜底的规则放后面。

2.4 切换 NS 后的观察期,别急着关旧服务

把 NS 切过去之后,全球 DNS 解析的收敛需要时间,通常是几小时到一两天不等。我的习惯是保留旧 DNS 服务商账号至少一周,确保所有解析都切过去之后再清理。观察期里要盯着几件事:证书自动签发是否成功(Cloudflare 的 Edge Certificate 会自动申请)、邮件收发是否正常、源站日志里回源 IP 是否已经变成 Cloudflare 网段。还有一个很容易漏的点:如果你用了 DNSSEC,需要先在旧服务商那里关闭 DNSSEC,再到 Cloudflare 开启,顺序反了会导致整个域名解析失败。

3. 计算层落地:Workers 与 Pages 的组合实践

3.1 先搞清楚 Workers 到底该干什么

很多刚接触 cloudflare-os 的人会把 Workers 当成一个“免费的云函数平台”来用,写一堆 CRUD 测试,然后发现限制很多就不玩了。实际上 Workers 的核心价值不在于“能跑代码”,而在于它运行在全世界的边缘节点上,你的请求在离用户最近的机房就被处理了,回源只在必须的时候发生。理解了这一点,你会发现它适合做这几类事情:请求转发与控制逻辑、A/B 测试开关、身份校验前置、API 聚合、静态站点的个性化渲染合成。

我在这个项目里给 Workers 分配的核心职责是:接管所有 API 子域的请求,做 JWT 校验、请求日志、数据聚合,然后决定是回源还是直接返回。相当于把传统架构里 Nginx 层 + 部分业务层做的事情搬到了边缘。这样做的好处很明显:恶意请求在到达源站前就被挡掉了,源站只需要处理可信的、已经过一遍逻辑的请求。

3.2 一个完整的 Worker 配置示例

下面这个 Worker 我起了个名字叫 api-gateway,功能是校验请求头里的 API Key,读写 KV 里的配置,然后决定是否把请求转发到源站 API。代码不复杂,但覆盖了几个关键点。

export default { async fetch(request, env, ctx) { const url = new URL(request.url); const apiKey = request.headers.get('X-API-Key'); // 1. 校验 API Key,非法的直接返回 401 const validKey = await env.CONFIG_KV.get('api_key'); if (!apiKey || apiKey !== validKey) { return new Response(JSON.stringify({ error: 'invalid api key' }), { status: 401, headers: { 'Content-Type': 'application/json' }, }); } // 2. 如果请求的是 /health,直接由 Worker 返回,不回源 if (url.pathname === '/health') { return new Response(JSON.stringify({ status: 'ok' }), { headers: { 'Content-Type': 'application/json' }, }); } // 3. 其他请求,带上校验结果和真实客户端 IP,转发到源站 const clientIP = request.headers.get('CF-Connecting-IP') || 'unknown'; const newHeaders = new Headers(request.headers); newHeaders.set('X-Client-IP', clientIP); newHeaders.set('X-Auth-Result', 'verified'); const originUrl = 'https://origin.example.com' + url.pathname + url.search; const originRequest = new Request(originUrl, { method: request.method, headers: newHeaders, body: request.body, }); const response = await fetch(originRequest); // 4. 给响应统一追加一个标记头,方便调试 const newResponse = new Response(response.body, response); newResponse.headers.set('X-Edge-Processed', 'cloudflare-worker'); return newResponse; }, };

部署的时候有个细节值得重点说:Worker 里的 env 变量有两种来源,一种是面板里设置的环境变量,一种是绑定的 KV 命名空间。上面代码里的 CONFIG_KV 就是在 Worker 设置里绑定好一个 KV namespace 后的引用名。环境变量适合存不经常变的值,KV 适合存配置项的运行时状态。我习惯把秘钥类信息放进环境变量,用 Terraform 管理,避免把敏感值直接写死在代码仓库里。

Worker 的 CPU 执行时间限制是 10 毫秒(免费套餐)。做聚合类计算时很容易超限,解决思路是把重计算拆成多个子请求并行执行,然后用 Promise.all 合并,或者把需要长时间运行的部分拆到 Queue 里异步处理。这里提醒一下:同步 fetch 到外部 API 的耗时是不算进 CPU 时间限制的,但会占用请求总时长,如果这个外部 API 响应慢了,整个请求也会慢。

3.3 Pages 托管前端,和 Worker 无缝配合

cloudflare-os 里前端托管这块我非常推荐 Pages。它支持从 Git 仓库自动构建部署,一个项目配置好之后,每次 git push 自动生成预览环境和生产环境。我这里用一个典型的架构:前端页面托管在 Pages,绑定一个自定义域名,构建时把页面静态文件直接推送到边缘节点,接口请求打到我前面写的 api-gateway Worker 上。Pages 还支持 Pages Functions,也就是在静态站点旁边挂一些动态逻辑,适合做表单提交、评论、站点搜索这类轻功能。我自己用 Pages Functions 给博客做了站内搜索的接口,完全不用再单开一台服务器。

Pages 构建时有个坑:默认的构建命令和输出目录是根据框架自动识别的,但识别不一定准确。如果你的项目用了自定义的构建流程,一定要在面板里手动指定 build command 和 build output directory。比如我用 Vite 构建前端,输出目录是 dist,如果之前没手动设置,Cloudflare 按默认行为构建出来的可能是个空白页。另外 Pages 的免费套餐每月的构建次数有额度,对个人项目来说基本用不完,但如果你绑定了多个仓库天天提交,也可能会触发超限,这个看官方文档确认即可。

4. 存储层落地:KV、R2 与 D1 的选型与边界

4.1 KV 适合什么,不适合什么,为什么

Cloudflare KV 是一个全局键值存储,读取是最终一致的,写入后需要几秒钟才能在全球所有节点生效。它有两种读取模式:经典 KV 的访问入口和更强的低延迟入口。我项目里把 KV 用在几个地方:存储配置项、存 API Key、存用户上次访问的时间戳、存临时生成的短链映射。它的优点是操作简单、API 清晰,Reading 非常快(正常几十毫秒内),写入也不需要考虑数据库连接问题。

但 KV 绝对不能当传统数据库用。它的限制包括:单个 key 的 Value 最大 25MB(实测建议控制在 1MB 以内,否则读取延迟明显);不支持范围查询、不支持条件更新、没有事务。我看到有人试着把业务订单数据存进 KV,然后做按用户查询,结果发现根本没有查询能力,只能靠额外的索引 key 自己维护,代码复杂得已经不像个人项目了。KV 的正确打开方式是:存“要么整个替换、要么整个读取”的离散数据,比如配置项、缓存片段、会话元数据。

4.2 R2 怎么当对象存储用,兼容 S3 能省很多事

R2 是 Cloudflare 的对象存储服务,兼容 S3 API,这意味着你之前用 AWS SDK 写的上传下载代码,改一下 endpoint 和密钥就能迁移过来。我在 cloudflare-os 里用 R2 存博客图片、用户上传的附件、以及每日备份的数据库导出文件。

一个让我放弃其他对象存储的决定性因素是 R2 的出口流量不收费。原本用其他对象存储,每次图片被 CDN 回源拉取都要付流量费,而 R2 本身就在 Cloudflare 的网络里,CDN 回源走内网通道,这部分流量是免费的,对个人项目来说等于省了一笔固定成本。配置上也很直观,在面板里创建 bucket,然后在 API 令牌里生成一个有读写权限的令牌,把 endpoint、access key id、secret access key 配到应用里即可。

R2 上传时要注意 CORS 配置。如果你小程序或网页里直接上传到 R2,需要先给 bucket 设置允许跨域的规则,允许的 Origin 写上你的站点域名,允许的方法写上 PUT、POST、DELETE,否则浏览器跨域直接报错。我最初就是因为没配 CORS,调试了一整个下午,最后才发现是控制台里三个下拉框没选对。还有一个经验是,R2 的公开访问有两种方式:一种是绑定自定义域名,直接静态托管;另一种是通过 Worker 鉴权后再返回对象。我通常用第二种:Worker 校验完登录状态后,再去 R2 里取文件返回,这样别人没法直接猜 URL 拖走你的所有资源。

4.3 D1 是最后加进拼图的数据库

D1 是 Cloudflare 的关系型数据库,基于 SQLite,支持 SQL 查询。在这个项目里,我用 D1 存结构性更强的数据:文章阅读计数、评论列表、短链的访问记录。D1 支持导出和导入,开发时本地可以用 CLI 做迁移,部署后用同一个 CLI 推送 schema。

对小型项目来说 D1 是一个很平衡的选择,但要注意它也不是没有代价:D1 基于 SQLite 单文件模型,写入并发有限,单次查询的结果集也不宜过大。我踩过一次坑:给文章列表做了全表查询,然后在前端做分页,结果数据量到几万行时查询耗时飙升,后来改成只需要分页的查询才解决。如果业务查询模式非常复杂,还是建议用外部 Postgres 或者换到 Supabase 这类服务,Cloudflare 也不是万能的。

4.4 存储选型速查

数据特征推荐产品原因与边界
经常全量替换的配置项KV读取快,写入简单,最终一致可接受
缓存片段、会话元数据KV分布式定位好,适合不计较秒级一致性的场景
图片、视频、备份文件R2存储成本低,出口流量免费,S3 兼容
结构化业务数据D1支持 SQL,够用但别设计超大并发
高频 CRUD + 复杂连接查询外部数据库Cloudflare 自研库不覆盖重查询场景

5. 安全与性能:WAF、缓存与速率限制的真正玩法

5.1 WAF 规则怎么配才不“误杀”用户

Cloudflare 的 WAF 分托管规则和自定义规则。托管规则是它的工程师维护的一套规则集,开箱即用,屏蔽已知攻击载荷;自定义规则是你自己写的条件匹配,比如某个路径只允许特定国家访问,或某个接口只允许特定 UA。

我见过很多人直接把托管规则开到“高”档位,然后发现后台访问记录里出现大量误杀。我的建议是:先用“模拟”模式观察一周,看看有多少合法流量命中了攻击规则。Cloudflare 的 WAF 支持维护模式,可以选择逻辑和操作,把模式设为“模拟”后规则仍然执行匹配但不会真正拦截。观察结束后,再决定哪些规则可以升级为“阻止”,并且给管理后台的路径单独写一条放行规则,确保自己以后还能正常访问管理界面。

还有一点,自定义规则里有个常见误区:以为设置了封锁 IP 就能结果一部分攻击,但分布式的攻击源 IP 根本封不过来。更有效的做法是按照请求特征来拦截:没有浏览器特征的 API 请求、固定短时间内高频重复、包含明显注入语句的请求。我发现用“Bot Score”这个字段配合自定义规则效果很好,比如 Bot Score 低于 30 的请求直接质询或拦截,能挡掉大量爬虫和扫描器。

5.2 缓存策略,别让“缓存”背黑锅

缓存调优是 cloudflare-os 项目里最值得花时间的一个环节。初学者最容易遇到的问题是:改了代码、清了 CDN 缓存,但用户看到还是旧页面。这个问题的根源通常是缓存层级不止一层:Cloudflare 边缘缓存一层,浏览器本地缓存一层,如果你开了 Caching 的“使用缓存头”并且源站发送了枚举的缓存头,还有可能被中间链路缓存。

我维护这个系统时用的缓存策略分三个维度讲:静态资源开 Cache Everything + Edge TTL 一个月;HTML 页面开“标准”缓存,TTL 设成几小时;API 响应只在返回头里声明Cache-Control: no-store。然后在 Cache Rules 里按路径做精细化控制。这里有一个非常实用的调试方法:在 Cloudflare 的 CDN 缓存命中率面板里看比例,如果命中率长期低于 80%,大多数情况是响应头里的 no-store/cache-control 写得不合理,或者同一 URL 内容老变,不存在“缓存就是不给力”这种玄学。

5.3 速率限制,给 API 加一道真正的保险

API 接口如果裸奔,迟早会被脚本刷。Cloudflare 的 Rate Limiting Rules 可以在边缘直接限制每个 IP 在一段时间内的请求数。我在 api-gateway 的 Worker 前面加了一条速率限制规则,规则很简单:匹配所有 /api/ 路径,每个 IP 每分钟最多 60 次请求,超过就返回 429。对个人项目的 API 来说,这个强度完全够用。

配置时要理解“按 IP 计数”和“按会话计数”的区别。如果业务允许同一出口 IP 下多个用户同时访问(比如公司网络),按 IP 计数很可能会误伤。这时可以按会话计数,就是在 Cookie 里种一个标识。但我实际用下来发现按会话计数有一个问题:无状态 API 的客户端不一定维持 Cookie,结果就是计数不稳定。折中方案是:敏感接口(登录、发送短信这类)严格限制 IP,普通接口只做 IP 总频控,不做接口级限制。这样既避免被刷,也不会干扰正常使用。

5.4 SSL/TLS 模式选错会导致回源失败

Cloudflare 面板里有一个 SSL/TLS 加密模式的选择,有几种模式:灵活加密、完全加密、完全加密(严格)。这个选项决定了边缘节点到源站的这一段怎么做 TLS。很多人选“允许”,结果发现站点循环重定向,或者源站证书验证失败。

我推荐直接选“完全加密(严格)”,前提是源站必须有有效的证书(哪怕是自己签的,但要在 Cloudflare 里上传或开启源站证书功能)。千万别选“灵活加密”,因为那意味着端到端之间有一段是明文传输,这对一个号称“操作系统”级别的基础设施来说说不过去。另外,如果你用自签名证书,务必在完全加密(严格)模式下把证书上传给 Cloudflare,否则源站握手直接失败,整站 521 错误。

6. 常见问题与排查技巧实录

6.1 域名解析一切正常,但网站就是打不开

这个问题的排查路径我建议按顺序来:先看 DNS 解析是否返回 Cloudflare 的 IP,再看证书是否签发成功,然后看源站是否能正常访问,最后看防火墙是否有拦截记录。实际项目里我遇到过两次:一次是切换 NS 后忘了重新验证域名所有权,导致证书一直签发不下来,浏览器显示证书错误;另一次是 DNS 记录里有一条 A 记录还指向旧的源站 IP,回源每次都失败,但控制台里看 DNS 又是“正常”的,因为只能看到代理状态是橙色云,并不知道回源目标已经失效。

排查这类问题的一个小技巧:用curl -I https://你的域名看返回头,如果能看到cf-ray这个 Header,说明边缘是通的,问题大概率在回源或者证书;如果连 Header 都没有,说明 DNS 或者网络链路本身就出了问题。

6.2 Worker 部署后请求一直报 10001

在 Workers 的请求错误代码里,10001 通常表示脚本执行失败,常见原因是代码抛了未捕获的异常、绑定变量不存在、或者外部 fetch 超时。我的排除方式是:先看 Worker 面板的实时日志,看报错堆栈具体在哪一行;再看绑定是否都配了(环境变量、KV namespace、R2 bucket 都是独立绑定项,容易遗忘);最后检查 Workers 脚本的模块格式是不是标准的export default { fetch() {} },有时候用错了模块系统,部署是成功的,运行时就是找不到入口。

还有一个容易踩的坑:本地用 wrangler 调试时正常,部署到线上就报错。最典型的原因是本地环境变量和线上环境变量不一致。比如本地没设置某个 key,代码里读到的就是 undefined,然后调用它的方法直接炸。为了解决这类问题,我给 Worker 代码里加了一个自检逻辑:启动时把必需的环境变量名列表遍历一遍,有缺失就直接返回 500,并在响应体里写明缺了哪个变量,这样部署完立刻知道自己哪里配置不对。

6.3 R2 上传文件一直跨域失败

这个问题在前文说过,多半是 CORS 配置没到位。但还有一种隐蔽的情况:如果你用 SDK 上传时带了自定义 Header(比如 x-amz-meta-*),那 CORS 里的 Expose Headers 和 Allowed Headers 都要相应放宽,否则浏览器预检请求直接失败,代码却只报一句莫名其妙的 “Network Error”。处理方法是,在 bucket 的 CORS 配置里把 Allowed Headers 设成*,Allowed Methods 选 GET、PUT、DELETE,Expose Headers 里加上ETag。这样设置后,浏览器层面的跨域问题基本能解决。

6.4 页面更新了,但用户还是看到旧版本

这个前面也提过,缓存的锅最冤枉。我的检查顺序是:先看 Cloudflare 的缓存命中状态,是HIT、EXPIRED还是MISS。如果是 HIT,说明边缘缓存还在服务旧内容;如果是 EXPIRED,说明边缘已经重新回源,但浏览器本地缓存过期时间还没到。针对第一种情况,在 Cache Rules 里手动清理 URL 即可;针对第二种情况,需要修改源站响应头里的Cache-Control,并配合页面引用的文件名加版本号。我现在的做法是:前端构建时给静态资源文件名加上内容哈希,html 本身设置为 no-cache,这样一劳永逸,不会出现“改了代码用户看不见更新”的问题。

症状常见原因解决办法
站点打不开,浏览器证书错误证书未签发或域所有权未验证重新验证域名,在 SSL/TLS 面板申请证书
API 返回 521回源失败检查源站 IP、防火墙是否放行 Cloudflare 回源网段
接口偶发超时Worker 回源 fetch 等待过久给 fetch 加超时控制,改用 Cache API 或队列异步处理
所有请求包 403WAF 托管规则误杀先切换成模拟模式,再按日志微调规则
页面总是旧版本多层缓存叠加清边缘缓存 + 改 Cache-Control + 静态资源加版本号

6.5 控制台操作很快,但踩坑全在细节配置里

如果你是从零开始照着这个项目搭,我的建议是:先把一套最简配置跑通,再逐步加东西。不要一开始就把 WAF、速率限制、缓存规则、多个 Worker 全部配齐,因为每加一个模块,排查问题的范围就会爆炸式扩大。我自己在第二次搭建这套环境时,是先只打通 DNS + Pages,确认静态站能全球访问,再加 Worker 处理 API,最后才加 WAF 和缓存精细策略。每加一层就观察运行状态一两天,复用这个思路能让你在问题定位时有个清晰的基准线。

7. 配置即代码:用 Terraform 把整套系统固化成 Git 仓库

7.1 为什么不用手点控制台

cloudflare-os 要称得上“系统”,就不能只靠控制台点来点去。人要点出上千条配置是不可能的,而且不可审计,不可回归。我用 Terraform 的 Cloudflare Provider 管理了几乎所有资源配置:DNS 记录、Workers 脚本、KV namespace、R2 bucket、WAF 自定义规则、Rulesets 规则。这样整个基础设施的状态就全部沉淀在一个 Git 仓库里,改动走版本控制,回滚可以靠 Git revert。

有人可能会问:这跟用 Control 面板有什么区别?区别主要在三方面:可复现性,全组配置可以从零恢复生成;可审计性,每条规则都有提交记录和原因;可协作,团队里每个人都有同一套状态。即使你只有一个人,配置即代码带来的情绪价值也很高,至少改坏了能快速知道改了什么。

7.2 一份最小的 Terraform 配置参考

下面是我管理 DNS 记录和 KV namespace 时的最小配置片段,也展示了 Cloudflare Provider 的基础用法。

terraform { required_providers { cloudflare = { source = "cloudflare/cloudflare" version = "~> 4.0" } } } provider "cloudflare" { api_token = var.cloudflare_api_token } resource "cloudflare_zone" "main" { zone_id = var.zone_id } resource "cloudflare_record" "www" { zone_id = cloudflare_zone.main.zone_id name = "www" value = "192.0.2.1" type = "A" proxied = true } resource "cloudflare_workers_kv_namespace" "config" { title = "config-kv" } resource "cloudflare_workers_script" "api_gateway" { name = "api-gateway" content = file("api-gateway.js") module = true }

这里有个坑可能刚上手的人会遇到:Cloudflare 的 Terraform Provider 要求 API Token 必须有对应资源的编辑权限,否则terraform apply会莫名其妙报 403。别问我怎么知道的,排查这个就花了大半天。建议创建 API Token 时直接选“编辑所有资源”的模板,跑通后再按最小权限原则收窄。

7.3 Secrets 与变量的版本管理

在 Terraform 里管理 Worker 环境变量有个要点:普通变量可以直接用secret_text字段,但更推荐把 Secret 放进 Terraform 的变量文件,然后用cloudflare_workers_secret资源挂上去。尤其要注意,Terraform state 文件里会以明文保存资源状态,如果你用了远程 state 存储(比如 Terraform Cloud),一定要确保访问权限足够严格。个人项目最省心的做法是:把 Terraform 部署在本地或 CI 里,state 存在本地 gitignore 忽略的目录,Secret 通过环境变量注入,不进仓库。

8. 实操心得与后续扩展建议

这套 cloudflare-os 我从最早只有一个静态博客,扩充到现在托管了个人博客、文档站、三个 API 服务和一个小的图片分享站点,整个基础设施的运维消耗被压到了极低。我平时基本不用进入 Cloudflare 控制台改配置,Git push 触发 Pages 构建和 Workers 部署,Terraform apply 更新 DNS 和规则,监控靠 Cloudflare Analytics 和 Workers 日志。忙的时候一个月也就打开一次面板。

给正在看这篇文章的读者几个我反复验证过的经验:第一,尽量少依赖控制台手动操作,所有改动都走 Terraform 是一件值得养成的习惯;第二,缓存规则和 WAF 规则一定先从“模拟/宽松”开始,观察清楚了再收紧;第三,Worker 的日志是你排查问题的第一现场,在开发环境就养成把关键事件打印出来的习惯,别等上生产了才想起来日志不够用;第四,Edge 平台迭代很快,每隔几个月回头看一眼官方文档,说不定你之前绕了半天的问题已经有新功能可以解决了。

如果你想在这条路上继续深入,我建议的方向是:把 Workers 从“请求入口”升级为“整个站点的编排层”,用它在数据返回前做后处理、聚合多个服务、做个性化实验。再往深走,可以把整个 cloudflare-os 的 Terraform 配置整理成一套可供朋友复用的模板项目,让新服务上线变成一条terraform apply的事。这套东西的迷人之处就在于,你搭建的不再是一个孤立应用,而是一个能持续生长、天然带网络、安全和加速属性的技术底座。

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询