05.3 · AWS Lambda 预置并发(Provisioned Concurrency)详解:冷启动、溢出、自动扩缩与成本

🇬🇧 English version | 📦 GitHub: https://github.com/geekchow/aws-lambda-guide

背景: 本文选自开源学习指南《AWS Lambda 心智模型》(中英双语)。全书用一个贯穿示例串联:网店 ShopFast 的 checkout 函数,周四通过 prod 别名把 v7 金丝雀发布到 v8,周五黑五开售前把预置并发(PC,Provisioned Concurrency)提到 400;文中的"第 N 步"即指该示例中的步骤,完整场景见 04 贯穿示例。
你在这里: 第 5 阶段,深入 3 / 7。示例第 3 步(金丝雀期间预热池拆分)、第 6 步(PC 扩到 400)、第 7 步(09:00 全热的第一波)、第 8 步(Bob 溢出)。

读完本文你将知道: PC(Provisioned Concurrency,预置并发)究竟预先创建了什么、它的生命周期、溢出如何发生、如何扩缩、成本几何,以及它如何失败。


1. 角色回顾

负责: 为某个版本或别名保持 N 个已初始化的执行环境就绪。出场于: 第 3 步(预热池跟随加权别名)、第 6 步(08:30 扩到 400)、第 7 步(09:00 第一波全部热服务)、第 8 步(池耗尽 → Bob 溢出)。

2. 内部设计

2.1 "预置"的精确含义

按需环境在第一个请求内部 运行 Init 阶段(启动扩展、引导运行时、执行你的顶层代码)。PC 把 Init 提前:
#mermaid-svg-FVLJJt6gUvXwFGNG{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-FVLJJt6gUvXwFGNG .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-FVLJJt6gUvXwFGNG .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-FVLJJt6gUvXwFGNG .error-icon{fill:#552222;}#mermaid-svg-FVLJJt6gUvXwFGNG .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-FVLJJt6gUvXwFGNG .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-FVLJJt6gUvXwFGNG .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-FVLJJt6gUvXwFGNG .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-FVLJJt6gUvXwFGNG .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-FVLJJt6gUvXwFGNG .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-FVLJJt6gUvXwFGNG .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-FVLJJt6gUvXwFGNG .marker{fill:#333333;stroke:#333333;}#mermaid-svg-FVLJJt6gUvXwFGNG .marker.cross{stroke:#333333;}#mermaid-svg-FVLJJt6gUvXwFGNG svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-FVLJJt6gUvXwFGNG p{margin:0;}#mermaid-svg-FVLJJt6gUvXwFGNG .label{font-family:"trebuchet ms",verdana,arial,sans-serif;color:#333;}#mermaid-svg-FVLJJt6gUvXwFGNG .cluster-label text{fill:#333;}#mermaid-svg-FVLJJt6gUvXwFGNG .cluster-label span{color:#333;}#mermaid-svg-FVLJJt6gUvXwFGNG .cluster-label span p{background-color:transparent;}#mermaid-svg-FVLJJt6gUvXwFGNG .label text,#mermaid-svg-FVLJJt6gUvXwFGNG span{fill:#333;color:#333;}#mermaid-svg-FVLJJt6gUvXwFGNG .node rect,#mermaid-svg-FVLJJt6gUvXwFGNG .node circle,#mermaid-svg-FVLJJt6gUvXwFGNG .node ellipse,#mermaid-svg-FVLJJt6gUvXwFGNG .node polygon,#mermaid-svg-FVLJJt6gUvXwFGNG .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-FVLJJt6gUvXwFGNG .rough-node .label text,#mermaid-svg-FVLJJt6gUvXwFGNG .node .label text,#mermaid-svg-FVLJJt6gUvXwFGNG .image-shape .label,#mermaid-svg-FVLJJt6gUvXwFGNG .icon-shape .label{text-anchor:middle;}#mermaid-svg-FVLJJt6gUvXwFGNG .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#mermaid-svg-FVLJJt6gUvXwFGNG .rough-node .label,#mermaid-svg-FVLJJt6gUvXwFGNG .node .label,#mermaid-svg-FVLJJt6gUvXwFGNG .image-shape .label,#mermaid-svg-FVLJJt6gUvXwFGNG .icon-shape .label{text-align:center;}#mermaid-svg-FVLJJt6gUvXwFGNG .node.clickable{cursor:pointer;}#mermaid-svg-FVLJJt6gUvXwFGNG .root .anchor path{fill:#333333!important;stroke-width:0;stroke:#333333;}#mermaid-svg-FVLJJt6gUvXwFGNG .arrowheadPath{fill:#333333;}#mermaid-svg-FVLJJt6gUvXwFGNG .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-FVLJJt6gUvXwFGNG .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-FVLJJt6gUvXwFGNG .edgeLabel{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-FVLJJt6gUvXwFGNG .edgeLabel p{background-color:rgba(232,232,232, 0.8);}#mermaid-svg-FVLJJt6gUvXwFGNG .edgeLabel rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-FVLJJt6gUvXwFGNG .labelBkg{background-color:rgba(232, 232, 232, 0.5);}#mermaid-svg-FVLJJt6gUvXwFGNG .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-FVLJJt6gUvXwFGNG .cluster text{fill:#333;}#mermaid-svg-FVLJJt6gUvXwFGNG .cluster span{color:#333;}#mermaid-svg-FVLJJt6gUvXwFGNG div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-FVLJJt6gUvXwFGNG .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-FVLJJt6gUvXwFGNG rect.text{fill:none;stroke-width:0;}#mermaid-svg-FVLJJt6gUvXwFGNG .icon-shape,#mermaid-svg-FVLJJt6gUvXwFGNG .image-shape{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-FVLJJt6gUvXwFGNG .icon-shape p,#mermaid-svg-FVLJJt6gUvXwFGNG .image-shape p{background-color:rgba(232,232,232, 0.8);padding:2px;}#mermaid-svg-FVLJJt6gUvXwFGNG .icon-shape .label rect,#mermaid-svg-FVLJJt6gUvXwFGNG .image-shape .label rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-FVLJJt6gUvXwFGNG .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mermaid-svg-FVLJJt6gUvXwFGNG .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mermaid-svg-FVLJJt6gUvXwFGNG :root{--mermaid-font-family:"trebuchet ms",verdana,arial,sans-serif;} 预置: Init 提前完成
环境空闲等待
配置 PC

提前数分钟
启动 + Init

不在请求路径上
请求到达
Handler:

150 ms
按需冷启动: 在请求内部
请求到达
启动微虚拟机

  • 拉取代码
    Init:

约 600 ms
Handler:

150 ms

图注:PC 不会让代码变快------它把启动 + Init 移出请求的延迟。

关键推论:

  • Init 时机不同。 对 PC 而言,Init 可能在首次调用前数分钟甚至数小时运行,且 10 秒 Init 限制被放宽(最长 15 分钟)。不要在 Init 中假设请求马上到来,比如计算"请求开始时间"或拉取短期令牌。
  • 代码可以分辨。 AWS_LAMBDA_INITIALIZATION_TYPE 的值为 provisioned-concurrency(对应还有 on-demand、snap-start)。
  • 环境仍会被回收。 Lambda 会定期替换 PC 环境(与其他环境一样),并在淘汰旧环境之前预初始化替代者,所以 Init 会再次运行------保持它幂等。
  • 一个环境一个请求 依然成立:PC = 400 意味着 400 个同时的热调用,而不是 400 RPS(Requests Per Second,每秒请求数)。

2.2 PC 可以挂在哪里

目标 允许?
已发布版本(checkout:8) 是
别名(checkout:prod) 是------跟随别名;若加权则拆分到 2 个版本
$LATEST,或指向 $LATEST 的别名 否
同时挂在别名和它指向的版本上 否(冲突)

PC 从并发限额中划出:它计入函数的预留并发(若设置了 RC(Reserved Concurrency,预留并发),则 PC ≤ RC),也计入账号限额(始终保留 100 未预留)。

2.3 生命周期

#mermaid-svg-Hq9Ial7Hh9NlzZiO{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-Hq9Ial7Hh9NlzZiO .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-Hq9Ial7Hh9NlzZiO .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-Hq9Ial7Hh9NlzZiO .error-icon{fill:#552222;}#mermaid-svg-Hq9Ial7Hh9NlzZiO .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-Hq9Ial7Hh9NlzZiO .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-Hq9Ial7Hh9NlzZiO .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-Hq9Ial7Hh9NlzZiO .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-Hq9Ial7Hh9NlzZiO .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-Hq9Ial7Hh9NlzZiO .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-Hq9Ial7Hh9NlzZiO .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-Hq9Ial7Hh9NlzZiO .marker{fill:#333333;stroke:#333333;}#mermaid-svg-Hq9Ial7Hh9NlzZiO .marker.cross{stroke:#333333;}#mermaid-svg-Hq9Ial7Hh9NlzZiO svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-Hq9Ial7Hh9NlzZiO p{margin:0;}#mermaid-svg-Hq9Ial7Hh9NlzZiO defs #statediagram-barbEnd{fill:#333333;stroke:#333333;}#mermaid-svg-Hq9Ial7Hh9NlzZiO g.stateGroup text{fill:#9370DB;stroke:none;font-size:10px;}#mermaid-svg-Hq9Ial7Hh9NlzZiO g.stateGroup text{fill:#333;stroke:none;font-size:10px;}#mermaid-svg-Hq9Ial7Hh9NlzZiO g.stateGroup .state-title{font-weight:bolder;fill:#131300;}#mermaid-svg-Hq9Ial7Hh9NlzZiO g.stateGroup rect{fill:#ECECFF;stroke:#9370DB;}#mermaid-svg-Hq9Ial7Hh9NlzZiO g.stateGroup line{stroke:#333333;stroke-width:1;}#mermaid-svg-Hq9Ial7Hh9NlzZiO .transition{stroke:#333333;stroke-width:1;fill:none;}#mermaid-svg-Hq9Ial7Hh9NlzZiO .stateGroup .composit{fill:white;border-bottom:1px;}#mermaid-svg-Hq9Ial7Hh9NlzZiO .stateGroup .alt-composit{fill:#e0e0e0;border-bottom:1px;}#mermaid-svg-Hq9Ial7Hh9NlzZiO .state-note{stroke:#aaaa33;fill:#fff5ad;}#mermaid-svg-Hq9Ial7Hh9NlzZiO .state-note text{fill:black;stroke:none;font-size:10px;}#mermaid-svg-Hq9Ial7Hh9NlzZiO .stateLabel .box{stroke:none;stroke-width:0;fill:#ECECFF;opacity:0.5;}#mermaid-svg-Hq9Ial7Hh9NlzZiO .edgeLabel .label rect{fill:#ECECFF;opacity:0.5;}#mermaid-svg-Hq9Ial7Hh9NlzZiO .edgeLabel{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-Hq9Ial7Hh9NlzZiO .edgeLabel p{background-color:rgba(232,232,232, 0.8);}#mermaid-svg-Hq9Ial7Hh9NlzZiO .edgeLabel rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-Hq9Ial7Hh9NlzZiO .edgeLabel .label text{fill:#333;}#mermaid-svg-Hq9Ial7Hh9NlzZiO .label div .edgeLabel{color:#333;}#mermaid-svg-Hq9Ial7Hh9NlzZiO .stateLabel text{fill:#131300;font-size:10px;font-weight:bold;}#mermaid-svg-Hq9Ial7Hh9NlzZiO .node circle.state-start{fill:#333333;stroke:#333333;}#mermaid-svg-Hq9Ial7Hh9NlzZiO .node .fork-join{fill:#333333;stroke:#333333;}#mermaid-svg-Hq9Ial7Hh9NlzZiO .node circle.state-end{fill:#9370DB;stroke:white;stroke-width:1.5;}#mermaid-svg-Hq9Ial7Hh9NlzZiO .end-state-inner{fill:white;stroke-width:1.5;}#mermaid-svg-Hq9Ial7Hh9NlzZiO .node rect{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-Hq9Ial7Hh9NlzZiO .node polygon{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-Hq9Ial7Hh9NlzZiO #statediagram-barbEnd{fill:#333333;}#mermaid-svg-Hq9Ial7Hh9NlzZiO .statediagram-cluster rect{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-Hq9Ial7Hh9NlzZiO .cluster-label,#mermaid-svg-Hq9Ial7Hh9NlzZiO .nodeLabel{color:#131300;}#mermaid-svg-Hq9Ial7Hh9NlzZiO .statediagram-cluster rect.outer{rx:5px;ry:5px;}#mermaid-svg-Hq9Ial7Hh9NlzZiO .statediagram-state .divider{stroke:#9370DB;}#mermaid-svg-Hq9Ial7Hh9NlzZiO .statediagram-state .title-state{rx:5px;ry:5px;}#mermaid-svg-Hq9Ial7Hh9NlzZiO .statediagram-cluster.statediagram-cluster .inner{fill:white;}#mermaid-svg-Hq9Ial7Hh9NlzZiO .statediagram-cluster.statediagram-cluster-alt .inner{fill:#f0f0f0;}#mermaid-svg-Hq9Ial7Hh9NlzZiO .statediagram-cluster .inner{rx:0;ry:0;}#mermaid-svg-Hq9Ial7Hh9NlzZiO .statediagram-state rect.basic{rx:5px;ry:5px;}#mermaid-svg-Hq9Ial7Hh9NlzZiO .statediagram-state rect.divider{stroke-dasharray:10,10;fill:#f0f0f0;}#mermaid-svg-Hq9Ial7Hh9NlzZiO .note-edge{stroke-dasharray:5;}#mermaid-svg-Hq9Ial7Hh9NlzZiO .statediagram-note rect{fill:#fff5ad;stroke:#aaaa33;stroke-width:1px;rx:0;ry:0;}#mermaid-svg-Hq9Ial7Hh9NlzZiO .statediagram-note rect{fill:#fff5ad;stroke:#aaaa33;stroke-width:1px;rx:0;ry:0;}#mermaid-svg-Hq9Ial7Hh9NlzZiO .statediagram-note text{fill:black;}#mermaid-svg-Hq9Ial7Hh9NlzZiO .statediagram-note .nodeLabel{color:black;}#mermaid-svg-Hq9Ial7Hh9NlzZiO .statediagram .edgeLabel{color:red;}#mermaid-svg-Hq9Ial7Hh9NlzZiO #dependencyStart,#mermaid-svg-Hq9Ial7Hh9NlzZiO #dependencyEnd{fill:#333333;stroke:#333333;stroke-width:1;}#mermaid-svg-Hq9Ial7Hh9NlzZiO .statediagramTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-Hq9Ial7Hh9NlzZiO :root{--mermaid-font-family:"trebuchet ms",verdana,arial,sans-serif;} PutProvisioned

ConcurrencyConfig
N 个环境

全部初始化
Init 出错 /

容量问题
N 改变,或别名

目标/权重改变
修复后重新设置
DeleteProvisioned

ConcurrencyConfig
IN_PROGRESS
READY
FAILED

图注:PC 是异步的------你请求 N,Lambda 报告 Allocated 逐步逼近 N,然后变为 READY。

数百个环境的分配通常需要一到几分钟;它同样受函数级扩缩速率约束(每 10 秒新增 1,000 个环境)。

2.4 溢出:PC 是下限,绝不是上限

#mermaid-svg-i23yenpXNgofhvGJ{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-i23yenpXNgofhvGJ .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-i23yenpXNgofhvGJ .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-i23yenpXNgofhvGJ .error-icon{fill:#552222;}#mermaid-svg-i23yenpXNgofhvGJ .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-i23yenpXNgofhvGJ .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-i23yenpXNgofhvGJ .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-i23yenpXNgofhvGJ .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-i23yenpXNgofhvGJ .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-i23yenpXNgofhvGJ .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-i23yenpXNgofhvGJ .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-i23yenpXNgofhvGJ .marker{fill:#333333;stroke:#333333;}#mermaid-svg-i23yenpXNgofhvGJ .marker.cross{stroke:#333333;}#mermaid-svg-i23yenpXNgofhvGJ svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-i23yenpXNgofhvGJ p{margin:0;}#mermaid-svg-i23yenpXNgofhvGJ .label{font-family:"trebuchet ms",verdana,arial,sans-serif;color:#333;}#mermaid-svg-i23yenpXNgofhvGJ .cluster-label text{fill:#333;}#mermaid-svg-i23yenpXNgofhvGJ .cluster-label span{color:#333;}#mermaid-svg-i23yenpXNgofhvGJ .cluster-label span p{background-color:transparent;}#mermaid-svg-i23yenpXNgofhvGJ .label text,#mermaid-svg-i23yenpXNgofhvGJ span{fill:#333;color:#333;}#mermaid-svg-i23yenpXNgofhvGJ .node rect,#mermaid-svg-i23yenpXNgofhvGJ .node circle,#mermaid-svg-i23yenpXNgofhvGJ .node ellipse,#mermaid-svg-i23yenpXNgofhvGJ .node polygon,#mermaid-svg-i23yenpXNgofhvGJ .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-i23yenpXNgofhvGJ .rough-node .label text,#mermaid-svg-i23yenpXNgofhvGJ .node .label text,#mermaid-svg-i23yenpXNgofhvGJ .image-shape .label,#mermaid-svg-i23yenpXNgofhvGJ .icon-shape .label{text-anchor:middle;}#mermaid-svg-i23yenpXNgofhvGJ .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#mermaid-svg-i23yenpXNgofhvGJ .rough-node .label,#mermaid-svg-i23yenpXNgofhvGJ .node .label,#mermaid-svg-i23yenpXNgofhvGJ .image-shape .label,#mermaid-svg-i23yenpXNgofhvGJ .icon-shape .label{text-align:center;}#mermaid-svg-i23yenpXNgofhvGJ .node.clickable{cursor:pointer;}#mermaid-svg-i23yenpXNgofhvGJ .root .anchor path{fill:#333333!important;stroke-width:0;stroke:#333333;}#mermaid-svg-i23yenpXNgofhvGJ .arrowheadPath{fill:#333333;}#mermaid-svg-i23yenpXNgofhvGJ .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-i23yenpXNgofhvGJ .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-i23yenpXNgofhvGJ .edgeLabel{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-i23yenpXNgofhvGJ .edgeLabel p{background-color:rgba(232,232,232, 0.8);}#mermaid-svg-i23yenpXNgofhvGJ .edgeLabel rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-i23yenpXNgofhvGJ .labelBkg{background-color:rgba(232, 232, 232, 0.5);}#mermaid-svg-i23yenpXNgofhvGJ .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-i23yenpXNgofhvGJ .cluster text{fill:#333;}#mermaid-svg-i23yenpXNgofhvGJ .cluster span{color:#333;}#mermaid-svg-i23yenpXNgofhvGJ div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-i23yenpXNgofhvGJ .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-i23yenpXNgofhvGJ rect.text{fill:none;stroke-width:0;}#mermaid-svg-i23yenpXNgofhvGJ .icon-shape,#mermaid-svg-i23yenpXNgofhvGJ .image-shape{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-i23yenpXNgofhvGJ .icon-shape p,#mermaid-svg-i23yenpXNgofhvGJ .image-shape p{background-color:rgba(232,232,232, 0.8);padding:2px;}#mermaid-svg-i23yenpXNgofhvGJ .icon-shape .label rect,#mermaid-svg-i23yenpXNgofhvGJ .image-shape .label rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-i23yenpXNgofhvGJ .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mermaid-svg-i23yenpXNgofhvGJ .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mermaid-svg-i23yenpXNgofhvGJ :root{--mermaid-font-family:"trebuchet ms",verdana,arial,sans-serif;} 有
没有
有
没有
已准入的 v8 请求
有空闲的

v8 PC 环境?
在热 PC 环境运行

无冷启动
有可复用的

空闲按需环境?
热运行

按需价格
新建按需环境:

冷启动

图注:PC 耗尽时请求溢出到按需而不是失败------限流是计数服务更早做出的另一项决策(05.4)。

需要关注的指标(使用 Maximum 统计):

指标 含义
ProvisionedConcurrentExecutions 此刻忙碌的 PC 环境数
ProvisionedConcurrencyUtilization 忙碌数 ÷ 已分配数(0--1)
ProvisionedConcurrencyInvocations 由 PC 服务的调用数
ProvisionedConcurrencySpilloverInvocations 没有拿到 PC 环境的调用数

2.5 用 Application Auto Scaling 扩缩 PC

PC 本身是一个静态数字。Application Auto Scaling 替你改变这个数字:

  • 计划扩缩(Scheduled scaling)------用于已知事件(黑五、09:00 开市)。可靠,因为它在需求之前行动。
  • 目标跟踪(Target tracking) ,基于 LambdaProvisionedConcurrencyUtilization(如目标 0.7)。被动式:依赖 CloudWatch 告警对若干个 1 分钟数据点的评估(约 3 分钟后扩容,缩容慢得多),所以它抓不住 30 秒的尖峰。要与计划的最小值搭配使用。

2.6 成本模型

只要 PC 处于配置状态,无论忙闲都要付费;运行时则按更低 的时长单价计费。us-east-1 x86 的示意价格(请以定价页为准,价格会变):

收费项 按需 使用 PC
保持环境预热(每配置 GB-s(Gigabyte-second,GB 秒)) ------ ≈ $0.0000041667
时长(每执行 GB-s) ≈ $0.0000166667 ≈ $0.0000097222
请求 每百万 $0.20 相同

经验法则:利用率持续高于约 60% 时,PC 比按需更便宜;低于此值时,你是在花钱买延迟,而不是省钱。SnapStart(Java、Python、.NET)是没有闲置成本的替代方案:它在发布时给已初始化的环境打快照,冷启动时从快照恢复------冷启动更快,但不是零。

3. 交互

邻居 契约
别名路由(05.2) 别名上的 PC 跟随其版本;权重变化触发重新分配。
计数服务(05.4) PC 计入预留/账号并发;PC 不准入也不拒绝请求。
分配 + 放置(05.5) PC 管理器请放置服务创建 N 个环境,并向分配服务登记为"预置、空闲"。
执行环境(05.6) Init 在分配时运行;handler 在请求时运行。
Application Auto Scaling 负责随时间改变 N;Lambda 只执行最新的 N。

4. ⚓ 回到示例------第 3、6、7、8 步

周四之前, prod 有 PC 50,全部在 v7 上:

bash 复制代码
aws lambda put-provisioned-concurrency-config \
  --function-name checkout --qualifier prod \
  --provisioned-concurrent-executions 50

第 3 步------周四 14:01 ,别名变为 v7 90% / v8 10%。PC 管理器重新分配,约 45 个热环境服务 v7、5 个服务 v8(切换期间 AllocatedProvisionedConcurrentExecutions 会波动)。Alice 的请求(第 4 步)找到了 5 个热 v8 环境之一。周四下午流量约 20 并发,5 个绰绰有余;若是更忙的日子,团队会在金丝雀窗口调高 PC。

第 6 步------周五 08:30,周一注册的计划任务触发:

bash 复制代码
aws application-autoscaling register-scalable-target \
  --service-namespace lambda \
  --resource-id function:checkout:prod \
  --scalable-dimension lambda:function:ProvisionedConcurrency \
  --min-capacity 50 --max-capacity 600

aws application-autoscaling put-scheduled-action \
  --service-namespace lambda \
  --resource-id function:checkout:prod \
  --scalable-dimension lambda:function:ProvisionedConcurrency \
  --scheduled-action-name black-friday-open \
  --schedule "at(2026-11-27T08:30:00)" \
  --scalable-target-action MinCapacity=400,MaxCapacity=600

aws application-autoscaling put-scaling-policy \
  --service-namespace lambda \
  --resource-id function:checkout:prod \
  --scalable-dimension lambda:function:ProvisionedConcurrency \
  --policy-name pc-utilization-70 --policy-type TargetTrackingScaling \
  --target-tracking-scaling-policy-configuration \
   '{"TargetValue":0.7,"PredefinedMetricSpecification":{"PredefinedMetricType":"LambdaProvisionedConcurrencyUtilization"}}'

prod 的 PC 变为 IN_PROGRESS;放置服务再创建 350 个 v8 环境,每个都以 AWS_LAMBDA_INITIALIZATION_TYPE=provisioned-concurrency 记录一次 Init。到约 08:33:

bash 复制代码
aws lambda get-provisioned-concurrency-config --function-name checkout --qualifier prod
# { "RequestedProvisionedConcurrentExecutions": 400,
#   "AllocatedProvisionedConcurrentExecutions": 400,
#   "AvailableProvisionedConcurrentExecutions": 400, "Status": "READY" }

第 7 步------09:00:2,000 RPS × 0.15 秒 ≈ 300 并发。利用率 = 300/400 = 0.75;溢出 = 0。每位顾客都在约 150 毫秒内完成。

第 8 步------09:05 :需求约 675 并发。400 个跑在 PC 上;约 275 个计入 ProvisionedConcurrencySpilloverInvocations。Bob 的请求就是其中之一 → 冷的按需环境,多出约 600 毫秒。目标跟踪看到利用率 1.0,开始把 PC 推向 600------但它的告警需要数分钟,所以尖峰的第一波仍要付出冷启动。明年的经验教训:计划值设为 700。

5. 失败行为

失败 症状 应对
PC 环境中 Init 抛异常 状态 FAILED;部署报错 "Invalid alias configuration for provisioned concurrency" 把别名回滚到上一个正常版本;修复 Init;发布新版本。
PC 耗尽 溢出 → 冷启动(而不是错误) 在已知高峰前计划扩容;对溢出设告警。
PC 大于预留并发或账号余量 put-provisioned-concurrency-config 被拒 先提高 RC / 账号限额。
新版本 PC 未 READY 就切换别名 新版本冷启动 等待 READY;加权切换期间超额预置。
忘了缩容 整个周末为闲置的 600 个环境付费 计划缩容任务;预算告警。

下一篇 → 05.4 调用前端与并发 · 返回 03 概念地图


📚 返回专栏目录

相关推荐
m0_547486662 小时前
《云计算应用与实践》全套PPT课件2026
云计算·云计算应用
一颗小行星!2 小时前
阿里云也有Cloudflare Pages,免费建站成功!
阿里云·云计算
金融小师妹3 小时前
事件驱动分析模型:9月PPI超预期与美联储利率预期对黄金价格的影响
人工智能·云计算·线性回归·pyqt
无风听海3 小时前
一文读懂 AWS IAM:从工牌、钥匙到统一登录
云计算·aws
Geek-Chow16 小时前
02 · AWS Lambda 是什么:一句话定义、边界与生态位置
云计算
Joy T18 小时前
阿里云全栈部署 Skill:环境检查、版本适配、灰度发布与回滚实践
阿里云·云计算·部署·skills·ai能力接入·版本冲突
腾讯云大数据19 小时前
从辅助驾驶到自主闭环:腾讯云ES的Agentic AIOps实践
elasticsearch·云计算·腾讯云
Geek-Chow21 小时前
03 · AWS Lambda 概念地图:6 个核心概念与 6 个关键组件如何协作
云计算
ABB自动化1 天前
本特利内华达3500系统
系统架构·云计算·系统安全·plc 控制器