C35

Serverless

点击正文段落选定收藏或划线位置;未选定时使用屏幕内第一段。

课内目录

1 Serverless 要回答什么

零售网站收到订单后,需要校验请求、保存订单,再通知仓库。业务刚上线时,每分钟可能只有几笔订单;促销开始后,短时间内又可能涌入大量请求。如果团队自行维护服务器,就要同时考虑应用部署、进程存活、机器容量和扩容时机。Serverless 要回答的问题是:能否把更多运行环境的管理交给平台,让开发者主要围绕请求和事件交付业务能力,并让计算资源随负载分配?

Serverless 通常译为无服务器,但服务器依然存在。变化的是使用者管理资源的方式和责任边界。开发者提交代码或运行包,声明触发条件、资源规格、执行身份和访问范围,由平台安排执行环境。平台可能把闲置环境回收,也可能保留环境供后续调用复用。开发者通常不必登录机器修复进程,但必须理解环境会出现、复用和消失,不能把某个进程永远存活当成业务前提。

函数即服务是常见形态:收到事件后运行指定入口,处理完成后返回结果。支持按请求伸缩的托管容器,也可能提供类似的使用方式;某些数据库、队列和工作流服务也提供按需管理能力。因此,Serverless 是资源管理与交付方式的描述,不等于某种编程语言,也不只等于短小函数。评价方案时,应具体询问谁负责扩缩容、哪些资源按什么单位计量、使用者还要配置哪些边界。

对订单接口而言,请求入口负责接收网络访问,执行环境负责运行校验逻辑,身份系统决定代码能读取哪些数据,网络规则决定它能到达哪些服务,数据库保存订单,日志与指标解释运行结果。把这些原语连接起来,才构成可用的服务。仅仅把原来的应用代码放进函数,并不会自动获得可靠的数据写入、合理的权限或可解释的失败记录。

订单服务中的 Serverless 原语与责任
订单服务中的 Serverless 原语与责任

这种模式适合流量有波动、事件来源清晰、任务可以分段处理的场景。例如上传商品图片后生成缩略图,或收到订单事件后生成通知。持续占用大量计算资源的任务、严格依赖长连接的处理、对首次响应极敏感的接口,则需要单独评估运行限制和成本。这里没有通用赢家,判断依据是业务能否接受平台的执行模型,以及节省的运维工作是否值得相应约束。

学习本课时,可以始终带着 3 个问题:谁触发执行,结果保存在哪里,负载增长时谁先遇到上限。第 1 个问题帮助识别调用与重试语义,第 2 个问题帮助区分临时环境与持久状态,第 3 个问题防止把计算弹性误认为整条服务链路的无限容量。后面的冷启动实验、磁盘误用和连接风暴,都可以从这 3 个问题出发解释。

2 事件触发、冷启动与并发边界

事件是一次处理需求的载体,可以是 HTTP 请求、队列消息、对象创建通知或定时任务。事件通常带有业务数据或数据位置,以及用于关联处理的标识。同步调用中,调用方往往等待结果;异步调用中,入口可能先确认接收,后台再处理。接收成功只说明系统接受了工作,不能直接解释为订单已经保存、通知已经发送。接口与页面必须表达这段差别。

当事件到来而没有可用环境时,平台可能需要准备环境、加载运行包,并执行应用初始化,这段额外开销常被称为冷启动。可复用环境接到后续事件时,通常可以跳过其中部分准备步骤,称为热调用。冷启动不是每次调用的固定组成部分,热调用也没有永远保持快速的保证。缓存失效、下游变慢和网络等待,都可能使已经复用环境的请求耗时增加。

从用户视角看,总等待时间可能包含入口处理、排队、环境准备、应用初始化、业务执行和结果传输。应用入口内部记录的耗时,只覆盖其中部分阶段。某次调用很慢,并不能单凭耗时就认定是冷启动。必须结合平台提供的初始化指标、应用初始化标记、环境标识和下游调用记录,判断额外时间究竟发生在哪里。

事件进入、环境准备与结果确认
事件进入、环境准备与结果确认

并发表示同一时间正在处理的调用数量,吞吐量表示单位时间完成的工作数量。以平均每秒到达 20 个请求、每个请求平均占用执行环境 0.5 秒为例,在稳定且没有明显排队时,平均在途调用约为 10 个。这个估算有助于理解容量,但不是峰值保证;突发到达、耗时分布、平台调度和单个环境允许的并发方式,都可能改变实际需要的环境数量。

平台通常对并发、扩容速度、执行时长或账户资源设有边界。超过边界的调用可能排队、被限制或失败,具体行为要看触发方式与配置。队列触发可以把突发转换成积压,但积压会增加业务等待时间,也可能超过消息保留期限。HTTP 调用如果没有等待空间,就需要明确返回繁忙状态,并让调用方按约定退避重试,而不是无限挂起连接。

并发上限还需要与数据库、外部接口等下游容量一起设计。计算环境可以快速增加,并不代表数据库连接数也会同步增加。要分别记录入口允许接收多少请求、执行层允许多少在途任务、下游允许多少连接,以及等待最多持续多久。读者在交互里逐步增加事件时,应观察请求去了哪里:进入执行、留在队列,还是被拒绝。只有把这些去向说清楚,弹性才成为可讨论的工程行为。

3 函数、容器与平台责任划分

函数模式通常要求开发者提供入口处理器,由平台决定何时调用。托管容器通常要求开发者提供镜像,并按约定监听端口或启动任务。前者常有更明确的事件适配方式,后者允许更自由地选择依赖、框架和启动方式。容器镜像也可能被用来打包函数,因此不能只凭交付物是镜像,就断定它采用哪种执行模型;应查看入口约定、实例生命周期和伸缩规则。

在函数模式下,平台往往负责宿主基础设施和受支持运行时的维护,开发者负责应用代码与打包依赖。在托管容器模式下,平台可以管理承载容器的机器,但镜像内的系统库、语言运行时及其更新往往仍由开发者负责。具体边界以服务约定为准。无论哪种模式,代码存在注入漏洞、订单状态设计错误或依赖版本过旧,都不能期待伸缩平台替团队解决。

部署是把代码版本和配置共同交付的过程。订单处理器至少需要入口、内存等资源规格、超时、触发规则、执行身份及数据库位置。代码版本没有变化而超时或身份发生变化,也可能改变业务行为。练习时应把这些配置纳入版本记录,让回滚能恢复需要的组合。发布后先观察少量真实路径,再逐步增加流量;环境准备成功只能证明程序能够启动,不能证明业务链路已经正确。

身份需要区分部署者身份与运行时身份。负责发布代码的人可以拥有更新处理器的权限,运行中的处理器则只需要完成自身业务所需的权限。例如保存订单的处理器可以写订单表,却不应因此获得删除备份或修改账户权限的能力。访问凭据应由受控机制提供并支持更新,不能硬编码进运行包,更不能通过日志输出。权限不足和网络不通都可能表现为调用失败,但修复路径不同。

网络连通也不是部署成功的附赠结果。处理器访问私有数据库,可能需要配置网络接入、名称解析和允许的端口;调用公网服务,又可能依赖出口路径。排查时需要分别问:目标地址能否解析,路径是否可达,访问规则是否允许,身份是否通过认证。不要看到连接超时就扩大全部权限,也不要把认证拒绝当成扩容不足。这里只认识这些边界,具体网络机制留给对应专题。

函数与托管容器的责任边界
函数与托管容器的责任边界

数据和可观测性同样属于应用责任。平台可以提供持久存储、日志接收和指标采集,但团队仍要定义订单什么时候算成功、哪些字段能记录、如何关联同一事件的多次尝试,以及告警由谁处理。对入门项目而言,先画出部署、身份、网络、数据、观测这 5 类配置,比先研究底层调度实现更有价值:它们直接决定代码是否能安全地完成用户要求的工作。

4 动手:测量一次冷启动时间线

实验目标是把首次请求的等待拆开,而不是追求某个平台的最短数字。准备独立的测试处理器,限制实验流量,使用不含真实订单的信息。处理器在模块加载时生成随机环境标识并记录初始化时间,在每次入口调用时记录请求标识、开始时间和结束时间。环境标识只用于观察复用关系,不应成为业务主键,也不应包含主机地址或访问凭据。

可以按下面的伪代码实现最小观测。单次调用耗时使用单调时钟计算,避免系统时间调整影响差值;日志时间则使用统一的墙上时钟,方便排序。程序内初始化测量只反映它能够看见的范围,不能覆盖平台在程序启动前完成的全部准备工作。

模块初始化开始:记录 init_begin
生成 env_id;准备应用依赖
模块初始化结束:记录 init_end

处理事件(event):
  读取 event.request_id
  start = 单调时钟()
  记录 request_id、env_id、阶段 entry
  执行固定的测试任务
  记录 request_id、env_id、阶段 exit、耗时
  返回 request_id 和测试结果

先部署新版本,然后从客户端发出 1 次请求,记录客户端总耗时和平台请求标识。随后串行发送 5 次相同请求,保持请求内容与资源配置不变,收集同样的字段。新版本的首次请求更有机会观察到初始化,但部署过程可能预先准备环境,所以不能保证它必然冷启动。短时间内连续请求,也不保证都进入同一个环境。判断时必须回到日志证据。

把记录排成时间线:客户端开始、平台可见的接收阶段、初始化记录、入口开始、业务结束、客户端收到结果。某些平台不会暴露全部阶段,可以在表中标为未知。假设客户端总耗时为 430 毫秒,入口内部为 80 毫秒,只能推断有约 350 毫秒发生在入口测量之外;不能把这段差额全部叫作冷启动,因为网络传输和入口等待也在其中。

冷启动实验的观测位置与未知区间
冷启动实验的观测位置与未知区间

再发起小规模并发,例如同时发送 4 次请求,观察是否出现新的环境标识与初始化记录。这个步骤用于比较环境复用和扩容期间的表现,不用于压测平台。测试后可以等待一段空闲时间再试,但空闲时间本身不是可靠的冷启动开关;平台没有承诺某个回收间隔时,不能把等待 10 分钟写成必现步骤。记录“此次未观察到新初始化”也是有效结果。

整理结果时,保留代码版本、资源规格、包大小、触发方式、样本数量和测试时间。同一组配置可以重复采样,分别查看观察到初始化与未观察到初始化的调用。只有少量样本时,展示原始值比宣称准确的高分位延迟更诚实。若准备比较依赖加载方式,每轮只改 1 个因素,避免同时修改内存和代码后无法解释差别。

最后写出有边界的结论,例如“本轮 6 次串行请求中,观察到 1 次应用初始化,该次客户端等待较长;平台准备阶段仍缺少独立数据”。这比“首次请求慢,所以冷启动耗时为全部差额”更有用。完成实验后移除不再需要的测试入口和临时资源,保留脱敏记录。真正需要改善的是用户等待,因此下一步应根据证据选择减少初始化工作、调整交互方式,或接受适当的首次延迟。

5 状态外置与超时取舍

执行环境中的变量、内存缓存和临时文件,都可能在环境被回收后消失。不同环境之间通常也不会自动共享这些内容。订单是否已创建、库存是否已扣减、某条事件是否已经处理,属于需要跨调用保留的业务状态,应写入合适的持久存储。状态外置不意味着所有数据都必须写数据库,而是先区分可以重新计算的临时结果与丢失后会破坏业务承诺的事实。

内存缓存仍然有价值。例如连接对象或只读配置可以在环境复用时减少重复准备,但缓存失效后必须能重新建立。代码不能假定上次调用写入的全局变量一定存在,也不能把全局变量当作当前请求的私有容器;部分执行模式允许环境内同时处理多个请求,错误共享可能导致数据串用。入门时的稳妥规则是:请求数据随请求传递,持久事实显式写入外部存储。

重试使状态设计更重要。客户端没有收到响应,并不代表处理器没有完成写入;队列消息也可能在处理成功后、确认前再次投递。给订单创建请求设置稳定的业务操作标识,让重复尝试能够识别同一次操作,是实现幂等的常用起点。仅仅先查询“是否存在”再写入还不够,因为并发尝试可能同时查到不存在;最终需要依靠存储提供的唯一约束、条件写入或事务保证关键状态转换。

超时是在等待价值与资源占用之间划边界。订单入口等待数据库、处理器等待外部接口、客户端等待入口,各自都有时间预算。应为下游调用设置明确截止时间,并给处理器留下记录失败、返回结果或确认消息所需的余量。例如入口预算为 3 秒时,不宜让内部某次调用独自等待 3 秒后再尝试记录和响应。超时值还需要遵守所用服务的限制,不能只在代码里声明愿望。

交互用固定任务耗时展示取舍:缩短等待上限后,更多慢任务被判为超时,单次尝试占用的时间减少;延长上限后,更多任务有机会完成,但在途任务和下游占用可能增加。这个演示不模拟真实计费,也不保证超时会终止远端操作。实际系统里,客户端断开、处理器超时和数据库停止执行是不同事件,不能把“我不等了”解释成“对方一定没有执行”。

因此,超时后的页面不应贸然提示用户重新创建订单。可以返回操作标识,允许查询处理状态;异步处理则需要持久记录处理中、成功或失败。业务截止时间到了之后,即使消息稍后还能执行,也要判断它是否仍有业务意义。复杂的跨系统一致性机制留待后续学习,本课先落实 3 件事:状态有可靠归属,重复尝试有识别方式,超时结果有后续查询或补救路径。

6 常见坑:把本地磁盘当事务存储

设想处理器收到订单后,把订单内容写进临时目录中的文件,再向客户端返回成功。单次测试时,可以读取刚写入的文件,结果看起来完全正确。连续几次请求如果恰好复用了环境,测试还可能继续通过。但促销流量触发新环境后,新环境看不到原来的文件;旧环境回收后,文件也可能消失。问题不是文件操作偶尔失败,而是把生命周期不匹配的存储当作了订单事实的归属。

即使文件恰好保留下来,也不代表它具备事务语义。多个处理器可能同时处理同一订单,不同环境各自写出“成功”文件,彼此无法协调。进程也可能在写入部分内容后退出,留下不完整记录。代码中的“文件已关闭”和业务中的“订单已可靠提交”是不同承诺。临时目录的容量限制、可写路径与清理行为还因平台而异,不能据此建立跨请求正确性。

类似误用也会发生在库存扣减:先读取本地数量,减去 1,再写回文件。增加计算并发后,不同环境持有不同副本,即使每个副本内部操作都顺利,整体库存也会失真。为临时文件增加锁只能约束锁覆盖的范围,不能自然扩展成跨环境事务。此时应把库存更新交给能够表达条件检查与原子修改的持久存储,而不是继续修补临时目录。

合理使用临时磁盘的例子是图片处理:从对象存储读取原图,在临时目录生成中间文件,再把最终缩略图上传到持久存储。处理中断后,可以根据原图重新生成。每次任务使用独立路径,检查空间与文件大小,成功或失败后尽量清理。对用户宣布任务成功之前,应确认最终产物已经写入目标存储,并记录可供再次查询的位置。

从临时文件到持久结果的安全提交顺序
从临时文件到持久结果的安全提交顺序

修复订单处理时,可以让数据库承担订单状态与唯一操作标识,让对象存储承担较大的附件。处理器只有在约定的持久写入成功后,才返回相应成功结果。如果后续通知是异步完成的,就把“订单已创建”与“通知已完成”分别表达。数据库写入后发布消息之间仍可能存在失败窗口,不能因为已经采用外部存储就声称所有环节具有原子性;如何可靠衔接事务与事件,需要进一步设计。

验证修复的重点是环境变化后业务事实仍然成立。通过显式标识不同测试环境,模拟重复事件和中途失败,检查最终是否只有符合规则的订单记录,用户能否查到稳定状态。测试数据应能清理,且不依赖特定环境永久存活。临时磁盘可以是效率工具,但只要某个结果决定用户的钱、库存或订单承诺,就必须说明它由哪种持久机制保证,以及失败后如何恢复。

7 案例:并发风暴打满下游连接

某订单事件处理器平时工作正常,活动开始后错误率迅速升高。团队看到函数平台仍有并发余量,便继续提高处理并发,结果数据库连接等待更长,任务超时更多。若消息失败后立即重试,待处理量还会继续增加。计算层扩容没有消除瓶颈,而是让更多任务同时争抢有限的下游连接,形成越慢越积压、越重试越拥挤的反馈。

先明确案例假设:数据库连接上限为 80,其他业务与维护预留 40,订单处理可使用的预算为 40。每个正在处理的事件最多占用 2 条连接,则订单处理并发应先限制在 20 以内。这里的除法只是容量预算起点,真实实现还需考虑连接池闲置连接、环境复用、共享数据库的其他访问者,以及每个事件是否真的同时持有 2 条连接。不能只按正在执行的 SQL 数量计算总连接。

假设突发到达 200 条事件,处理器每条平均占用 0.5 秒,在并发为 20 且下游稳定的理想条件下,吞吐量约为每秒 40 条,处理这批任务至少需要约 5 秒。真实等待还会增加调度和重试开销。如果用户可以接受这段异步延迟,队列可保存待处理事件,消费者按预算取出;如果用户必须同步获得结果,就需要在入口限制接收量,并清楚返回繁忙信息。

排查时先沿事件路径关联证据:入口到达量是否上升,执行并发是否增加,数据库活跃或已建立连接是否接近上限,获取连接的等待是否增长,随后才看超时和重试。若数据库连接并未吃紧,就不应仅凭高延迟套用连接风暴解释。可观测数据应区分“等待连接”和“执行查询”,因为前者提示资源分配问题,后者可能涉及查询本身或存储性能。

并发风暴的证据链与处理分支
并发风暴的证据链与处理分支

缓解措施从停止放大开始:限制消费者并发,给连接获取设置等待上限,缩小每个环境的连接池,并让可重试错误按退避策略再次尝试。连接池大小乘以可能同时存在的环境数量,是需要关注的量;保留的空闲连接也可能消耗数据库预算。重试要有次数与时间边界,无法自动处理的事件应进入可追踪的失败通道,供后续分析与补偿,而不是永远在主队列循环。

限流后,数据库错误率下降并不代表事故已经结束,还要观察积压数量、最老事件年龄和订单完成时间。只有队列能持续排空,且没有再次冲击下游,恢复才成立。之后可以减少每条事件占用的连接、缩短持有时间,或评估下游扩容。代理连接等能力可能有帮助,但需要确认它解决的具体限制。本课的关键结论是:可接受的处理速度由链路中的约束共同决定,执行环境数量只是其中 1 项。

8 把弹性假设写进事件驱动方案

架构图中的箭头往往只写“订单事件”,却省略了决定运行结果的条件。事件由谁生成,发送成功意味着什么,接收方什么时候确认,重复投递是否可能发生,这些都应进入方案。对入门订单服务,可以把对外承诺拆开:入口确认订单请求已经被可靠接收,后台处理器完成业务校验和持久写入,查询接口展示当前状态。每段承诺都需要对应可观察的事实。

事件本身至少要能表达事件标识、业务操作标识、类型、产生时间和必要的数据或数据引用。事件标识用于跟踪某条消息,业务操作标识用于识别同一次业务请求;它们的用途不应混淆。事件内容还应有清楚的数据约定,避免生产方改字段后使消费者全部失败。敏感数据尽量减少传播,处理日志只保留排障需要的标识和经过控制的信息。

弹性假设应写成可检查的条件。例如“订单消费者并发上限为 20,每个环境连接池不超过约定值,数据库为其他业务保留连接预算”。只写“自动扩容,保证高可用”无法指导配置。还要说明当到达速度持续超过处理速度时,最大允许积压是多少、最老事件能等待多久,以及达到边界后是停止接收、延后处理还是明确拒绝。队列是有限缓冲,不能消除长期容量缺口。

失败语义需要与状态转换一起描述。数据库写入失败时,事件可以在退避后重试;已成功写入但确认丢失时,重复投递应返回已有结果或安全跳过重复效果;数据格式不合法时,持续重试通常无益,应留下可定位的失败记录。对于库存等受顺序影响的操作,也不能默认平台保证所有事件全局有序。先明确业务所需范围,再选择服务能力与处理规则。

观测方案至少覆盖请求到达量、执行耗时、错误率、并发、限制次数、队列积压与年龄、下游连接使用情况。日志使用请求、事件和业务操作之间的关联字段,使团队能回答“这笔订单目前在哪里”。告警应对应用户影响,例如订单等待超过承诺时间,而不仅是某个环境出现错误。发布时观察新旧版本处理同类事件的表现,并确保回滚后仍能读取已经产生的数据。

成本同样要服从这些假设。按次执行、执行时长、内存规格、存储、网络和观测可能分别计量,失败与重试也可能产生费用。任务排队期间是否计入某项执行费用,需要查看具体计量规则。方案可以先列出费用来源和预期负载范围,不急于给出看似精确的单价结论。能说明正常路径、失败路径和积压路径各自消耗哪些资源,才算把“按需使用”变成可审查的设计。

9 从Serverless走向微服务架构(C36)

当订单接口、库存处理和通知任务分别部署时,很容易把它们称为微服务。但 Serverless 主要讨论计算如何交付和运行,微服务主要讨论业务如何划分、服务如何协作,以及团队如何独立演进。函数数量增加不自动形成合理的服务边界,同一个业务能力也可能由多个函数、容器任务和数据存储共同实现。下一课需要从业务职责重新观察这些运行单元。

以订单和通知为例,通知失败通常不应该撤销已经创建的订单,因此它们可以通过清楚的事件契约协作。库存扣减和订单确认之间的关系则更紧密,不能只因为能够增加 1 个函数,就假定拆开后更简单。拆分会引入网络失败、消息延迟、版本协调和状态一致性问题。先说清楚谁拥有哪份数据、谁承诺什么结果,再讨论是否独立部署,更容易做出适度的设计。

这里可以检查已经学到的边界。执行边界说明任务在哪个环境运行、何时可能被回收;容量边界说明并发与下游资源如何配合;状态边界说明事实保存在哪里;责任边界说明平台和团队分别维护什么。微服务进一步要求业务边界清楚:哪个服务有权改变订单状态,其他服务通过什么接口或事件了解变化,是否允许直接修改对方的数据。

Serverless 可以承载微服务,也可以承载单体应用的接口或零散后台任务。微服务同样可以运行在自行管理的服务器、容器平台或混合环境中。选择关系取决于业务与运维约束,而不是技术名称之间的固定搭配。对较小团队而言,把业务边界清楚的应用先部署成较少的运行单元,可能比过早拆成大量函数更容易观察和维护;是否拆分,应由实际独立演进需求推动。

把本课案例交给下一课时,保留 3 份材料:包含身份、网络与数据位置的链路图,说明触发、确认与重复处理的事件约定,以及并发、超时、连接预算和观测项的配置说明。这些材料能帮助判断某次拆分是否改变了用户承诺,也能指出新增网络调用会把失败窗口放在哪里。它们比单纯罗列部署单元更能支撑架构讨论。

还应保留不确定性。例如冷启动实验没有覆盖全部平台准备阶段,连接预算只针对当前负载与连接模型,任务耗时也可能随订单内容变化。把这些条件写进设计,后续就能随着测量更新判断。进入 C36 时,我们将继续追问服务职责与协作方式,而不是假定更多部署单元必然更可靠。可靠性来自明确的承诺、受控的边界,以及失败后仍然可解释和可恢复的业务状态。

放进方案里

在订单服务方案中,先写清采用 Serverless 的目的:由平台管理执行环境的分配与回收,团队负责业务正确性、依赖、权限及容量配置。入口接收请求后,为同一次业务操作保留稳定标识;需要等待较长时间的工作进入持久队列,由后台处理器消费。用户可通过操作标识查询状态,接收成功、订单创建成功和后续通知完成分别表达,不混用成功含义。

部署说明列出代码版本、资源规格、触发方式与超时预算。执行身份只授予所需数据访问权限,网络路径允许访问指定数据库与依赖服务。订单事实保存在数据库,附件与最终处理产物进入持久存储,内存和临时磁盘只承担可重建的工作。重复事件通过业务标识与存储约束控制效果;写入后通知的失败窗口另列处理规则,不宣称跨系统操作天然原子。

容量说明把入口接收、队列等待、执行并发和下游连接放在同一条链路中。若数据库为订单提供 40 条连接预算,每个执行任务最多占用 2 条,则先以 20 作为并发上界,再根据环境连接池和实际测量收紧配置。明确最大等待时间、重试退避与失败去向。超过业务截止时间的事件应有处理规则,不能因为资源空闲便继续执行已经失效的业务动作。

验收时观察正常调用、出现初始化的调用、重复投递、下游变慢和突发积压。记录客户端等待、处理耗时、连接等待及最老事件年龄,保留请求与业务标识的关联。告警围绕订单完成承诺设置,发布与回滚均检查状态兼容。最后列出执行、存储、网络及观测的计量来源,并为重试预留成本空间,使弹性、可靠性和费用都建立在明确假设上。

10 小结:下一步微服务架构(C36)

Serverless 把更多执行环境管理交给平台,同时要求应用适应环境变化、重复事件和有限容量。冷启动要沿时间线测量,业务状态要有持久归属,并发要受下游预算约束,超时要配套后续查询与补救路径。

自测时试着解释:为什么客户端超时后仍可能查到订单?为什么增加执行并发反而使成功率下降?为什么连续读取到临时文件不能证明它适合保存订单?如果答案能分别指向执行与响应的区别、下游资源边界和状态生命周期,就已经掌握本课主线。下一课 C36 将讨论微服务架构,进一步确定服务职责、数据归属与协作契约。

同阶段相关课

AI 答疑

默认关闭。启用后,只发送本课标题、最近阅读的屏幕内正文摘录(最多 6000 字)与本次问题。

配置自己的服务