面向哲思的编程与架构
笔记哲思阅读动态搜索RSS 订阅
切换到深色模式
搜索
RSS 订阅
切换到深色模式
© 2026 Vic Chen. All rights reserved.CC BY-NC-ND 4.0
← 笔记
现代计算的基础设施(二):并发的重新发现

现代计算的基础设施(二):并发的重新发现

2026年4月7日3,0489分钟

Lambda 的真正瓶颈不是冷启动,是「一请求一实例」的并发模型——每个请求独占一个执行环境,哪怕 90% 的时间都在等 I/O。Node.js 的事件循环本就能并发处理几十个请求,Fluid Compute 没有发明新技术,只是把这个三十年前就存在的并发模式带回了 Serverless 世界。


目录
  • 1. Serverless 的承诺与代价
  • 2. 冷启动的解剖
  • 3. 一请求一实例:被忽视的瓶颈
  • 4. Node.js 事件循环为什么天然适合并发
  • 5. Fluid Compute:把并发带回 Serverless
  • 5.1 控制平面的设计
  • 5.2 最大并发数的设定
  • 5.3 实例生命周期与预热
  • 6. 什么时候不该用 Serverless
  • 7. 传统长连接服务 vs Fluid Compute
  • 8. 本站情况
  • 9. 专线 SaaS 的映射
目录
  • 1. Serverless 的承诺与代价
  • 2. 冷启动的解剖
  • 3. 一请求一实例:被忽视的瓶颈
  • 4. Node.js 事件循环为什么天然适合并发
  • 5. Fluid Compute:把并发带回 Serverless
  • 5.1 控制平面的设计
  • 5.2 最大并发数的设定
  • 5.3 实例生命周期与预热
  • 6. 什么时候不该用 Serverless
  • 7. 传统长连接服务 vs Fluid Compute
  • 8. 本站情况
  • 9. 专线 SaaS 的映射
目录
  1. 1. Serverless 的承诺与代价
  2. 2. 冷启动的解剖
  3. 3. 一请求一实例:被忽视的瓶颈
  4. 4. Node.js 事件循环为什么天然适合并发
  5. 5. Fluid Compute:把并发带回 Serverless
  6. 5.1 控制平面的设计
  7. 5.2 最大并发数的设定
  8. 5.3 实例生命周期与预热
  9. 6. 什么时候不该用 Serverless
  10. 7. 传统长连接服务 vs Fluid Compute
  11. 8. 本站情况
  12. 9. 专线 SaaS 的映射
架构基础设施Serverless云原生
相关文章
  • 01
    现代计算的基础设施(五):一次请求的完整旅程2026/05
  • 02
    现代计算的基础设施(四):在边缘执行代码2026/04
  • 03
    现代计算的基础设施(一):隔离的代价2026/04
← 上一篇现代计算的基础设施(一):隔离的代价
下一篇 →现代计算的基础设施(三):边缘不是一种技术

评论

© 2026 Vic Chen · 面向哲思的编程与架构CC BY-NC-ND 4.0

上一篇:现代计算的基础设施(一):隔离的代价讨论了隔离方案的设计空间。这篇聚焦一个更具体的问题:Serverless 架构的核心瓶颈到底是什么,业界为什么把它诊断成「冷启动」,正确的诊断应该是什么。

1. Serverless 的承诺与代价

Serverless/FaaS 的核心承诺是:只写函数逻辑,不管服务器。平台负责弹性伸缩、故障恢复、容量规划。计费按实际执行时间,而不是预留实例。

这个模型对架构师有真实的吸引力:

  • 流量波动不需要手动扩缩容
  • 没有流量时不产生计算成本
  • 运维边界清晰,平台承担基础设施

代价是执行模型的约束——函数实例是无状态的,随时可能被销毁,也随时可能从零启动。这个启动过程就是「冷启动」。


2. 冷启动的解剖

一次 Lambda 函数调用,如果没有可用的热实例,需要经历以下阶段:

图1:Lambda 冷启动各阶段耗时分解

真实的冷启动时间分布很宽,从几百毫秒到几秒,主要取决于:

  • 代码包大小:node_modules 越大,下载和挂载越慢。
  • 运行时:Node.js 比 Python 慢,Java 更慢(JVM 启动)。
  • 顶层代码:模块初始化时做了多少工作(建数据库连接、加载配置等)。

多年来,围绕「消灭冷启动」有大量工程实践:减小 bundle 大小、懒加载依赖、预留并发(Provisioned Concurrency)……这些都是有效的,但都在治标。

真正的问题不是冷启动,而是为什么冷启动这么频繁。


3. 一请求一实例:被忽视的瓶颈

Lambda 的并发模型可以用一句话描述:一个执行环境同一时间只处理一个请求。

这意味着,如果你的函数同时收到 100 个请求,Lambda 会启动(或复用)100 个独立的执行环境。

图2:Lambda「一请求一实例」并发模型

对于一个处理数据库查询的 API 函数,执行时间线大约是这样的:

图3:典型 API 请求执行时间线——实际 CPU 工作时间不足 12%

这个函数的总执行时间 225ms,但 CPU 实际工作时间不到 25ms。剩余 200ms 全部在等待 I/O(建连接、等查询结果)。

在这 200ms 里,执行环境的 CPU 是完全空闲的。但 Lambda 的并发模型不允许这个空闲的执行环境处理其他请求——它在等,其他请求只能另开新环境。

这就是真正的浪费。 不是冷启动,是实例利用率。


4. Node.js 事件循环为什么天然适合并发

理解 Fluid Compute 的解法,需要先理解 Node.js 的并发模型。

Node.js 是单线程的,但它能并发处理 I/O——这不是矛盾,而是事件循环(Event Loop)的设计。

图4:Node.js 事件循环与 libuv 线程池架构

当 Node.js 执行 await db.query(sql) 时:

  1. 事件循环把 I/O 请求交给 libuv 线程池(或操作系统 epoll/kqueue(Chen 注:Linux 的 `epoll` 和 macOS/BSD 的 `kqueue` 都是操作系统提供的 I/O 事件通知机制,允许单个线程同时监听大量文件描述符(socket、管道等)的就绪状态,而无需为每个连接创建线程。libuv 在底层根据平台自动选择其中一种。))
  2. 事件循环立即返回,开始处理其他任务
  3. I/O 完成后,回调被推入队列,事件循环在下一个 tick 执行它

这意味着,一个 Node.js 进程在等待数据库响应期间,完全可以开始处理另一个请求的逻辑——只要那个请求也很快进入 I/O 等待状态,CPU 就不会成为瓶颈。

对于典型的 web API(大量时间在等数据库、等外部服务),一个 Node.js 进程并发处理几十甚至上百个请求是完全可行的,CPU 利用率依然很低。

这不是新发现。这是 Node.js 从 2009 年就在做的事(Chen 注:Ryan Dahl 于 2009 年 11 月在首届欧洲 JSConf 上发布了 Node.js,核心动机正是解决「一请求一线程」模型在高并发下的资源浪费问题。他在演讲中以 Apache 为反例,展示了事件循环如何用单线程处理大量并发 I/O。[→ Wikipedia](https://en.wikipedia.org/wiki/Node.js#History)),也是 Nginx 相对于 Apache 的核心优势(Chen 注:Nginx 由 Igor Sysoev 于 2004 年发布,明确以解决 [C10K 问题](https://kegel.com/c10k.html)(单机同时处理一万个连接)为设计目标。其事件驱动架构使单个 worker 进程能处理数万并发连接,而 Apache 的 prefork/worker MPM 在同等并发下内存占用高出数十倍。[→ Inside NGINX](https://blog.nginx.org/blog/inside-nginx-how-we-designed-for-performance-scale))所在。Serverless 的「一请求一实例」模型,反而是一种倒退。


5. Fluid Compute:把并发带回 Serverless

Vercel 的 Fluid Compute 本质上是一个并发模型的修正:允许一个执行环境并发处理多个请求。

图5:Fluid Compute「一实例多请求」并发模型

同样是 100 个并发请求,Lambda 需要 100 个执行环境,Fluid 可能只需要 10 个——因为每个环境并发处理 10 个请求,而这些请求大部分时间都在等 I/O。

5.1 控制平面的设计

实现这个模型,控制平面需要解决一个调度问题:如何把请求路由到有剩余并发容量的实例?

图6:Fluid Compute 控制平面请求路由与冷启触发时序

每个执行环境持续向注册表上报当前并发数和最大容量。调度器维护一个实时的容量视图,优先把请求投递给容量充足的实例,只在所有实例都满载时触发冷启动。

5.2 最大并发数的设定

每个执行环境的最大并发数(max_concurrency)是一个需要调优的参数:

  • 设置过高:CPU 密集型请求会互相竞争同一个线程,响应时间劣化
  • 设置过低:I/O 等待期间 CPU 空闲,实例利用率低,冷启更频繁

对于典型的 web API(I/O 密集),并发数可以设置较高(几十到上百)。对于 CPU 密集型任务(图像处理、加密运算),并发数应设为 1——退化回 Lambda 的经典模型。

图7:max_concurrency 配置与请求类型的映射关系

Vercel 目前对 Fluid Compute 的默认最大并发数是根据函数配置的内存大小动态计算的。

5.3 实例生命周期与预热

Fluid 的实例不是用完即销毁的。一个实例处理完请求后会保持存活,等待下一个请求——这就是「热实例复用」。

但热实例的保活是有成本的(即使没有请求也占用内存),所以平台需要一个回收策略:

图8:Fluid Compute 实例生命周期状态机

空闲超时后实例被销毁,下次请求触发新的冷启动。这就是为什么低流量函数依然会遇到冷启——不是并发模型的问题,是实例保活策略的问题。

Lambda 的 Provisioned Concurrency(预留并发)解决的是这个问题:花钱让指定数量的实例永远不被销毁,保证零冷启,但需要持续付费。


6. 什么时候不该用 Serverless

Fluid Compute 解决了实例利用率的问题,但 Serverless 模型还有一些场景不适合:

  • 长连接服务:WebSocket、Server-Sent Events、gRPC streaming——这些需要持久的有状态连接,Serverless 的无状态实例模型从根本上不匹配。

  • CPU 密集型批处理:视频转码、大规模数据聚合——这类任务需要稳定的 CPU 资源,Serverless 的弹性启停带来的调度开销反而是负担。

  • 极低延迟要求:即使热实例复用,Serverless 的调度路径(API 网关 → 调度器 → 实例)比直接命中一个始终在线的进程多几毫秒。对于 P99 延迟要求在个位数毫秒的场景,这不可接受。

  • 有状态计算:需要在内存中维护大型数据结构(如内存数据库、机器学习模型缓存)的服务,每次冷启都需要重新加载状态,成本无法接受。

适合 Serverless不适合 Serverless
HTTP API(REST / GraphQL)WebSocket / 长连接
事件处理(Webhook / 消息队列消费)CPU 密集批处理
定时任务(Cron Job)内存状态服务
边缘函数(请求改写、鉴权)极低延迟(P99 < 5ms)

7. 传统长连接服务 vs Fluid Compute

理解差异的直觉模型:

传统长连接(Railway/Render(Chen 注:Railway 和 Render 是两个典型的「始终在线」PaaS 平台,部署后进程持续运行,无冷启动,适合需要长连接或内存状态的服务。计费按实际运行时长,即使没有流量也持续计费。))Lambda 经典模型Fluid Compute
实例生命周期永远在线按请求启停按需启动,空闲保活
并发模型进程内多线程/事件循环一请求一实例一实例多请求
冷启动无(始终在线)有(每次启动新实例)低(热实例复用)
闲时成本高(始终付费)无低(短暂保活后销毁)
峰值扩容手动或慢速弹性毫秒级弹性毫秒级弹性
状态可以有内存状态无状态无状态

Fluid Compute 是在「完全无状态的弹性」和「始终在线的长连接」之间的一个工程折中——它把事件循环的并发优势带回 Serverless,同时保留了弹性伸缩和按需付费。


8. 本站情况

一些API(评论读写、阅读量更新、内容审核)用 Fluid Compute 是合适的:

  • 流量低且不均匀:白天有请求,深夜没有。长连接服务会让机器在深夜空转付费。
  • I/O 密集:每个 API 请求都要访问 Upstash Redis(HTTP 协议),90% 的时间在等网络。Fluid 的并发复用恰好能利用这段等待时间。
  • 无状态:评论和阅读量数据在 Redis 里,不需要进程内状态。

唯一不适合的部分是 OpenAI Moderation API 的调用——这个也是 I/O 等待为主(等 OpenAI 响应),仍然适合 Fluid。

如果评论系统有实时通知(「有人回复了你」的 WebSocket 推送),就需要一个单独的长连接服务,不能跑在 Fluid 上。


9. 专线 SaaS 的映射

把这个并发模型映射到专线 SaaS 场景,问题变成:如何为有限的、可预测的 B 端并发流量设计计算层?

公有云 Serverless 面对的是不可预测的互联网流量,弹性伸缩是核心需求。专线 SaaS 的流量特征截然不同:

  • 客户数量固定:不是无限的互联网用户,是已签约的 N 家金融机构。
  • 流量可预测:交易时段高峰,夜间批处理,可以提前规划。
  • SLA 要求严格:金融客户对延迟和可用性的 SLA 要求往往高于互联网产品。
图9:专线 SaaS 计算层三层架构——常驻层、弹性层与批处理层
  • 架构建议:不要把 Fluid/Serverless 当成替代所有常驻服务的银弹。在专线 SaaS 里,延迟敏感的核心交易路径应该是常驻服务;Fluid 模式适合报表、导出、通知等 I/O 密集的辅助功能。这样既利用了弹性模型降低非核心路径的成本,又保证了核心路径的延迟稳定性。

  • 容量规划:专线 SaaS 的优势是流量可预测。可以基于历史数据做确定性的容量规划(而不是依赖弹性伸缩),为每个客户分配固定的计算配额,配合 Fluid 的并发复用,在保证 SLA 的前提下最大化机器利用率。


下一篇:现代计算的基础设施(三):边缘不是一种技术