ARC 5让系统可以运行和排查第 19–22 章

第 21 章 —— Runtime 生命周期与流量准入

本章目标: 本章完成后,开发者能够用 Runtime 状态、registry freeze、readiness 和关闭顺序定义部署生命周期,不把 Spring Context 存在当成 DSM 已就绪。

学习目标

  1. 解释 CREATED → STARTING → RUNNING → STOPPING → CLOSED
  2. 知道集合为何在启动时冻结注册。
  3. 区分 liveness、readiness 与 diagnostics。
  4. 设计关闭入口、后台任务、membership 和资源释放顺序。

前置条件

案例进度

履约服务开始滚动发布。旧实例需要先停止接收新请求,再释放本地资源;新实例只有在集合冻结、membership/sync 启动并进入 RUNNING 后才接流量。否则一次部署会制造「应用已启动但协调面未准备好」的窗口。

状态机是调用许可表

Runtime 生命周期与注册冻结

状态 允许的主要动作 部署含义
CREATED 注册集合、读取静态 identity 还不能接业务流量
STARTING 冻结 registry,启动生命周期组件 readiness 为 false
RUNNING 服务本地集合操作与后台协作 isReady() 为 true
STOPPING 停止入口与后台任务 从负载均衡摘除
CLOSED 不再使用 Runtime 资源已经释放
ERROR 读取 lastErrorMessage,执行恢复策略 不接流量,不能伪装就绪

为什么启动时冻结 registry

collection descriptor 参与 capability/descriptor 广告和 sync route。节点已经开始通信后再悄悄增加集合,会产生「部分 peer 已知、部分 peer 未知」的动态契约窗口。默认 registry 在 start 时 freeze,后续注册被拒绝;Spring 生命周期测试也确认启动后 Runtime 已 RUNNING。

若未来需要动态注册,应设计显式迁移协议,而不是绕过 freeze。

Liveness 与 Readiness 不同

Spring Context 创建中、Runtime STARTING 或 ERROR 都不应对外报告 ready。DsmRuntimeLifecycle 在 context close 时停止 Runtime,但部署平台仍要先摘流量,不能把 JVM 关闭钩子当完整优雅下线协议。

关闭顺序的业务含义

推荐顺序:

  1. readiness 置 false,阻止新流量。
  2. 等待本地业务请求和短任务排空。
  3. 停止订阅消费者、repair/sync scheduler 等后台入口。
  4. 关闭 Runtime/membership/传输资源。
  5. 记录未完成、uncertain 或需补偿的业务动作。

DSM close 释放本地资源,不会自动回滚已经提交的订单事务或外部副作用。

反例与故障注入

实验

cd submodule/dsm
mvn -q -pl dsm-runtime,dsm-spring-boot-autoconfigure -am \
  -Dtest=DefaultDsmRuntimeTest,DefaultDsmCollectionRegistryTest,DsmAutoConfigurationTest,DsmSpringBootSmokeTest \
  -Dsurefire.failIfNoSpecifiedTests=false test

完成 lifecycle-drill.json,为每个状态写允许动作、readiness 和失败处理。

实验验收卡

字段 内容
运行命令 上述 Runtime registry 与 Spring lifecycle 聚焦测试
输入或故障 启动、冻结后注册、上下文关闭、启动失败
可观察结果 状态转换明确;late registration 被拒绝;close 后 lifecycle 停止
证据等级 E2:真实 Runtime 与 Spring ApplicationContext 生命周期
本实验未证明 部署平台 drain、真实负载均衡摘除、长事务补偿或容器强杀行为

回顾

下一步

第 22 章建立容量测量合同:用 JMH 回答一个具体热路径问题,而不是把一次短测数字写成生产 SLA。

证据链接