追踪一次真实请求在本站上的完整旅程:DNS 缓存怎么决定故障切换窗口,BGP Anycast 如何在网络层完成就近路由而不是在 DNS 层,TLS 为什么终止在边缘 PoP 而不是数据中心,Middleware 的异步写入如何不阻塞主请求,CDN 缓存命中与否如何决定是否触碰 Fluid Function。最复杂的评论提交路径走了所有关键组件——Firecracker 隔离、Fluid 并发复用、OpenAI 内容审核、Redis 并发写入。最后把同一条链路映射到专线 SaaS 架构:约束不同,方案不同,但每一层要解决的问题是一样的。
这是系列的最后一篇。前四篇分别讲了隔离模型、并发设计、路由机制和边缘运行时。这篇把它们串起来,用一次真实的请求把所有概念落地。
我们追踪两条链路:
然后对比:同样的请求,在专线 SaaS 架构下是什么样的。
在进入细节之前,先建立整体的分层模型:
每一层对应前面某篇文章的核心概念:BGP Anycast(第三篇)、V8 Isolate 的 Middleware(第四篇)、Fluid Function 的并发模型(第二篇)、microVM 隔离(第一篇)。
用户在浏览器输入 whchen.dev,第一件事是 DNS 解析。
76.76.21.21 是 Vercel 的 Anycast IP,全球多个 PoP 同时宣告这个 IP 段——这里 DNS 只是把请求导向一个 Anycast IP,真正的「就近路由」发生在网络层,不是 DNS 层(第三篇讲过 GeoDNS 的局限性)。
TTL 是 60 秒,这意味着 Vercel 的故障切换有 60 秒的 DNS 缓存窗口,但 BGP 层面的 Anycast 切换不受 TTL 影响。
浏览器拿到 IP 76.76.21.21,发起 TCP 连接。这个 IP 被全球多个 Vercel PoP 同时宣告:
BGP 路由器根据 AS-PATH 长度选择最近的 PoP。对于国内用户,通常落到香港或新加坡节点(Vercel 没有大陆节点)。
TCP 连接建立后,进行 TLS 握手。TLS 在边缘 PoP 终止,而不是在 Vercel 的区域数据中心——这让 TLS 握手只需要用户到 PoP 的 1~2 RTT,而不是到数据中心的 RTT。
TLS 握手完成后,HTTP 请求进入 Vercel 的处理链。每个请求——无论是静态资源还是 API——都会经过 Middleware。
Middleware 运行在 V8 Isolate 里(Edge Runtime),只用了 fetch 发起 HTTP 请求到 Upstash Redis——完全在 Web 标准 API 范围内,不依赖任何 Node.js 专有 API(第四篇讲的架构约束)。
Redis 的连接是 HTTP 而不是 TCP 长连接——这是 Upstash 的设计,让 Serverless 函数不需要维护连接池(第二篇讲到 Serverless 无状态模型的配套存储设计)。
Middleware 执行完毕,请求进入缓存层。这是路径分叉的关键节点:
本站绝大多数页面在构建时已经静态生成(Next.js SSG(Chen 注:Static Site Generation:Next.js 在构建阶段预先渲染所有页面为静态 HTML,部署后直接由 CDN 分发,无需在请求时调用 Fluid Function。与之对应的是 SSR(服务端渲染,每次请求都动态生成)和 ISR(增量静态再生,允许后台按需重新生成已缓存页面)。)),缓存命中率很高。用户访问一篇已有缓存的文章,整个响应在边缘 PoP 完成,不会触碰 Fluid Function。
缓存键不只是 URL——Vercel 还会考虑 Vary 头(如 Accept-Encoding)。深色/浅色主题通过客户端 CSS 变量切换,不影响缓存键,不会导致主题维度的缓存爆炸。
当请求需要动态处理时(API 请求、ISR 页面过期),请求从边缘 PoP 转发到最近的区域数据中心,进入 Fluid Function 执行层。
这里发生的事情,综合了前两篇的核心概念:
注意两件事同时发生在这里:
如果是页面请求(不是 API)且缓存未命中,Fluid Function 执行的是 Next.js 的 RSC(React Server Components)(Chen 注:React Server Components:组件在服务端执行,可以直接读取文件系统、访问数据库,渲染结果以 RSC payload 格式传给客户端。与传统 SSR 的区别在于:RSC 支持流式传输,`<Suspense>` 边界内的子树可以异步渲染后单独 flush,不需要等全树完成;客户端也不需要 hydrate 纯服务端组件,减少了 JS bundle 体积。)渲染。
RSC 的渲染是流式的——<Suspense> 边界内的组件可以异步渲染,HTML 分多个 chunk 逐步发送给浏览器,而不是等全部渲染完再一次性发送。这让用户能更早看到页面内容(首字节时间 TTFB 更低)。
MDX 的 rehype 插件链(代码高亮、mermaid 图、数学公式)在这个阶段全部在服务端完成,客户端拿到的是已处理好的 HTML,不需要在浏览器端再做解析和渲染。
评论提交是本站最复杂的 API 路径,完整走了所有关键组件:
这条链路的延迟主体是 OpenAI Moderation API 的响应时间(100~300ms)。如果想优化,可以改为异步审核——先乐观写入,标记为「待审核」状态,Moderation 完成后再更新状态。但对于个人站点的评论量,同步审核是可以接受的。
把各阶段的典型延迟汇总:
| 阶段 | 典型耗时 | 发生条件 |
|---|---|---|
| DNS 解析 | 10~50ms | 首次访问或缓存过期 |
| TCP + TLS 握手 | 20~80ms(到 PoP) | 首次连接,HTTP/2 复用后为 0 |
| Middleware 执行 | 5~20ms | 每次请求(异步不阻塞) |
| CDN 缓存命中 | 1~5ms | 静态资源、已生成页面 |
| Fluid Function 冷启 | 200~800ms | 实例被销毁后首次请求 |
| Fluid Function 热执行 | 10~50ms | 热实例复用 |
| Redis 读写(HTTP) | 5~30ms | 评论 API、阅读量 |
| OpenAI Moderation | 100~300ms | 评论提交 |
对于站点的主要场景(浏览文章),命中 CDN 缓存后端到端延迟在 30~100ms,主体是 DNS + TCP + TLS,与计算层无关。
同样一次请求,放到专线 SaaS 架构里,每一层对应关系如下:
逐层对照:
DNS / BGP Anycast → 专线路由:公网靠 BGP 把流量路由到最近 PoP,专线靠 OSPF(Chen 注:Open Shortest Path First:链路状态路由协议,每台路由器维护整个网络的拓扑图,用 Dijkstra 算法计算到每个目的地的最短路径。收敛速度快(秒级),是企业和运营商内网最常见的 IGP(内部网关协议)。) 或 SDN(Chen 注:Software-Defined Networking:将路由决策从硬件转移到集中式控制器(如 OpenFlow 控制器),网络设备只负责转发,控制逻辑由软件统一管理。优势是可编程、策略灵活,代价是控制器本身成为单点。) 把流量路由到最近数据中心。路由协议不同,但解决的是同一个问题:多入口、就近转发、故障自动切换。
TLS 终止在边缘 → TLS 终止在接入节点:公网的 TLS 在 PoP 终止,减少握手 RTT;专线 SaaS 的 TLS 在客户专线接入点终止,同样是减少回中心数据中心的握手往返。
CDN 缓存层 → 接入层缓存:公网 CDN 缓存静态资源;专线场景里,接入层可以缓存变化频率低的业务数据(如配置、参数表、行情快照),减少对中心数据库的访问,同时节省专线带宽。
Fluid Function → 应用服务:公网靠 Fluid 的并发复用提高实例利用率;专线场景里,同样可以在容器内用 Node.js 事件循环处理并发 I/O 请求,不需要为每个请求开新进程——这是第二篇的核心思路,与平台无关。
Upstash Redis(HTTP API)→ 内部数据库:公网选 Upstash 是因为它用 HTTP 协议,Serverless 友好;专线场景网络稳定,可以用传统 Redis 长连接(连接池复用),不需要 HTTP 包装层,延迟更低。
对比下来,真正的差异不是技术方案,而是约束条件:
| 约束维度 | 公网站点 | 专线 SaaS |
|---|---|---|
| 流量特征 | 不可预测,弹性是第一需求 | 可预测,容量规划优先于弹性 |
| 用户分布 | 全球分散,多 PoP 就近接入是第一需求 | 接入点固定,网络拓扑可控 |
| 运维模式 | 成本敏感,托管平台是默认选择 | 合规与审计要求,自建基础设施是默认选择 |
| 缓存价值 | CDN 缓存降低计算层压力 | 专线带宽有限,本地缓存价值更高 |
公网场景下,Vercel 提供的是一套「把基础设施复杂度全部托管给平台」的方案——你不需要理解 BGP、不需要管 Firecracker、不需要设计控制平面,直接 vercel deploy 就能得到一个全球分发的高可用服务。
专线 SaaS 下,这套复杂度你必须自己承担——但理解了公网平台是如何解决这些问题的,你就有了设计自己基础设施的参照系:用 OSPF 替代 BGP Anycast、用接入层缓存替代 CDN、用容器替代 microVM(或在需要强隔离时选 microVM)、用控制平面与数据平面分离替代「一台服务器跑所有东西」。
这个系列的价值不在于把 Vercel 的方案照搬到专线环境——那做不到,也没必要。而在于建立一个用于推导决策的思维框架:每一层要解决什么问题,有哪些解法,各自的代价是什么。约束不同时,答案自然不同,但推导路径是一样的。
系列完结。五篇文章覆盖了从隔离机制到网络路由、从并发模型到运行时设计的完整技术栈,每一篇都从第一性原理出发,最终落地到这个博客的真实架构和专线 SaaS 的实践映射。