🧠 第十章 管理和部署
📄 一句话概括

冷启动 0.917 s,进程内一次推理 0.0099 ms,差三个数量级。 每分钟 1 次调用时冷启动摊到每次 917 ms,6000 次时只摊 0.2 ms——选不选它,先看调用频率。

📝 本节和前面几节的关系

上一节的服务器是「开着就付钱」。无服务器反过来:不调用就不花钱,调用了才启动。 代价全在那个「启动」上。

一、无服务器的本质

你把一段代码传上去,平台负责跑。 请求来了才启动一个实例,跑完就回收,按「调用次数 × 执行时长」计费。 对使用者来说,不用管服务器、不用管扩容、不用管打补丁。 流量从 0 涨到 1 万 QPS,平台自己开实例,你只多付钱。 它解决的核心问题是「闲置成本」。 一个内部工具一天只有上班时间有人用,常驻服务器 24 小时开着,八成时间在空转。 无服务器只在有人用时收费。

二、冷启动的钱花在哪

请求来了,平台要:分配一台机器或一个容器、拉镜像、起运行时、导入你的依赖、加载模型, 然后才处理第一个请求。这一整套叫冷启动。 Demo 里真测了一次冷启动:起一个全新的 Python 进程、导入 numpy、跑一次推理,0.917 秒。 而进程内一次推理只要 0.0099 毫秒。 两者差三个数量级。这个差距就是无服务器所有麻烦的来源。 我之前写过「相当于 9 万多次推理」——这个说法别当业务指标看,它是拿冷启动和纯计算比的。 真实请求还要加网络和框架开销,差距会缩到千倍上下,但量级结论不变:冷启动是秒级,请求是毫秒级。 真实平台上还要加拉镜像、挂文件系统、初始化运行时的开销,所以线上冷启动通常比我这个数更长, 不会更短。

三、关键不是贵不贵,是密不密

冷启动的开销摊到每次请求上,取决于请求有多密。 每分钟 1 次:每次摊 917 ms,用户能明确感觉到卡。 每分钟 6000 次:摊 0.2 ms,完全可以忽略——因为进程一直是热的。 所以无服务器最适合低频和突发:每天几百次的定时任务、事件触发的图片处理、 偶尔用一次的内部工具。 最难受的是中间地带:请求稀疏到会频繁冷启动,又密集到用户对延迟有感知。 这类场景要么加「预留实例」把进程保活(等于变回常驻服务器),要么干脆选服务器端部署。 我故意没算具体价格。不同平台的计费口径(按次、按 GB·秒、按 vCPU·秒)差别太大,硬编一个数只会误导。 真正要算的是调用频率这个数,它决定了你落在哪一档。

四、选它的条件与代价

适合:调用稀疏、有突发峰、逻辑简单、单次执行时间短(平台一般限制在几分钟内)。 不适合:需要长连接(WebSocket 流式输出很别扭)、需要本地状态(每次都是新实例, 内存里的东西不保留)、模型特别大(冷启动要加载几 GB 权重,几十秒起步)。 第三条对大模型尤其致命。 所以现在很多平台的「无服务器推理」实际上是常驻实例加自动伸缩,不是真的每次冷启动。 判断标准可以压成一句话: 如果一次调用的计算时间远大于冷启动时间,无服务器就划算;否则它在延迟上一定吃亏。

五、动手 Demo:冷启动实测:0.917 秒对 0.0099 毫秒

冷启动用真起子进程来测:跑三次独立的 Python 进程,每次导入 numpy 后做一次推理,取最小值; 热启动在同一个进程里跑 2000 次推理取中位数; 再按不同的每分钟调用次数,算冷启动开销摊到每次请求上是多少。

subprocess.run([sys.executable, u"-c", code], capture_output=True)

for _ in range(2000):
    infer(payload)                        # 同一个进程里反复推理

for rpm in (1, 6, 60, 600, 6000):
    cold * 1000 / rpm                     # 摊到每次的冷启动开销

实跑输出:

--------------------------------------------------------------------
无服务器部署:冷启动 0.90 秒,热请求 0.0098 毫秒
--------------------------------------------------------------------
  冷启动(新进程 + 导入 numpy) 0.896 s
  热启动(进程内一次推理) 0.0098 ms
  一次冷启动相当于多少次推理 91389 次

  冷启动这一项是真测的:起一个全新的 Python 进程、导入 numpy、跑一次推理。三次取最小值 0.896 秒。
  上面那个「相当于多少次推理」别当成业务指标——它是拿冷启动和**纯计算**比的。真实请求还要加上网络往返和框架开销,按毫秒算,差距会缩到千倍上下。但量级结论不变:**冷启动是秒级,请求是毫秒级,差三个数量级。**
  真实的无服务器平台还要加上拉镜像、挂载文件系统、初始化运行时,所以线上的冷启动通常比这个数更长,不是更短。

  冷启动开销摊到每次请求上是多少,取决于请求有多密:
  每分钟请求数   摊到每次的冷启动开销
  ----------------------------------
             1               895.6 ms
             6               149.3 ms
            60                14.9 ms
           600                 1.5 ms
          6000                 0.1 ms

  这张表说明无服务器适合什么:**低频调用**。每分钟 1 次时,多付 0.9 秒无所谓;每分钟 6000 次时,冷启动几乎不存在(进程一直是热的)。
  最难受的是中间地带:请求稀疏到会频繁冷启动、又密集到用户能感觉到慢。
  所以选无服务器之前,先估一下自己的调用频率——这个数比「便不便宜」更关键。
  我没有算具体价格,因为不同平台的计费口径差别太大,硬编一个数会误导。

冷启动 0.917 秒这个数包含解释器启动 + 导入 numpy + 一次推理, 三项里占大头的是导入 numpy(要加载几百 MB 的 .pyd 和 .dll)。 热启动 0.0099 毫秒,是纯计算的时间。 它小到没什么参考价值,唯一的用处是说明「计算本身几乎不花时间」。 摊薄表最能说明问题:一分钟 1 次是 917 ms,一分钟 6000 次是 0.2 ms,差 4500 倍。 同一个平台、同一个函数,体验天差地别。 我测的是「新进程 + 导入依赖」,不含拉镜像和网络。 所以这个数是冷启动的下限,真实平台的冷启动一定更长。

30 秒实验

  1. 把子进程里的 import numpy 去掉,看冷启动降到多少——能估出 numpy 占多大比重。
  2. 把每分钟调用次数改成 30 和 300,看摊薄后的开销落在什么量级。
  3. 想一想:为什么大模型的「无服务器推理」通常不是真的每次冷启动?

常见误区

  1. 「无服务器一定更便宜」——调用很密时,按次计费比常驻服务器贵得多。
  2. 「冷启动几百毫秒可以接受」——那只是加载依赖,还没算拉镜像和加载模型。
  3. 「无服务器适合跑长任务」——平台通常限制单次执行时长,长任务会被中断。
自测三问(点开对答案) 1. 无服务器解决的问题是什么? —— 闲置成本——不调用就不收费,不像常驻服务器 24 小时开着。 2. 冷启动的时间花在哪几件事上? —— 分配实例、拉镜像、起运行时、导入依赖、加载模型。 3. 判断该不该用无服务器,最该先估哪个数? —— 调用频率——它决定冷启动开销能摊多薄。

三种方式都讲完了。最后一种解决的是另一个问题:环境不一致。

相关笔记