feat: add bounded business state observability

This commit is contained in:
2026-09-18 20:44:41 +08:00
parent bea8efa790
commit 5284206731
18 changed files with 450 additions and 12 deletions

View File

@@ -1,6 +1,6 @@
# 数据模型与实现基线
更新:2026-09-18。数据库统一禁止外键。当前已实现任务执行、安全重试、运行中取消、计划调度、队列限速/背压和应用配额;优先级及节点公平领取已实现;可靠订阅核心、HTTP/WSS、管理与消费 SDK 已实现,独立 Inbox 场景已实现,流程编排继续开发。
更新:2026-09-18。数据库统一禁止外键。当前迁移版本为26;000026只增加固定业务观测读取所需索引,不增加实体或字段。当前已实现任务执行、安全重试、运行中取消、计划调度、队列限速/背压和应用配额;优先级及节点公平领取已实现;可靠订阅核心、HTTP/WSS、管理与消费 SDK 已实现,独立 Inbox 场景已实现,流程编排继续开发。
## 1. 模块与依赖
@@ -245,3 +245,7 @@ Event.WorkflowID为只读STORED生成列,从原不可变事件派生流程归
新运行器将PENDING信号的消费、拒绝或过期与原状态事件同事务保存,批量拒绝分32条追加但整笔事务原子提交。公开查询核对固定版本全部队列、步骤/信号归属及历史激活。原始事件按数据库记录时间分页,版本与时间均不构成可靠消费水位。详见[状态时间线接口](api/workflow-events.md)与[验证报告](reports/phase-5-events.md)。
升级先停止旧写入节点,应用000025再启新版本,防止混合节点继续遗漏信号转换;生成列和索引涉及历史行扫描与可能的表重建,需预演维护窗口、磁盘和锁等待。严格SQL模式下先校验十六进制字符再转换,异常历史范围保留NULL,不清理原记录。
## 有界业务观测索引(000026)
000026只增加三组读取索引:`pulse_tasks(state,available_at,id)`、`orbit_deliveries(state,available_at,id)`和`weave_instances(state,updated_at,id)`。它们服务于后台有界观测,不改变任何模型字段、状态机、事务边界或授权规则,也不包含外键或级联。采样器只使用代码固定的表、索引、状态和列名,每个状态最多读取10000条;结果达到上限时必须通过指标暴露截断,不能把样本数解释为全库精确数量。迁移后仍要求服务层 `CheckSchema` 验证零外键,真实升级见[有界业务采样报告](reports/phase-6-business-observability.md)。

View File

@@ -59,7 +59,7 @@ P4/P5定时等待与后续查询轮次的实现及回归记录见[时钟报告](
### P6 首批实施顺序
1. 已补[首批可复现故障工具](reports/phase-6-fault-boundaries.md):A04“派发已提交但消息尚未送达”、W01/W13事务提交结果不明,以及W16最终回执/旧PENDING结果重放/下一轮竞争。每个切点必须有实际数据库或进程证据,不能用响应错误推断事务是否已提交,也不能用普通SIGNAL竞争替代最终查询场景。
2. 已实现[基础运行观测](api/observability.md):HTTP/WS、数据库连接池、后台批次和进程指标,以及可离线验证的告警规则;独立采集监听默认关闭,固定指标目录拒绝动态标签。仍需受理/授权/完成阶段延迟与持久吞吐、流程推进延迟、重试/核查/恢复量、待处理与到期积压、发送队列及生产采集/通知验证。
2. 已实现[基础运行观测](api/observability.md)及[有界业务状态采样](reports/phase-6-business-observability.md):HTTP/WS、数据库连接池、后台批次、固定状态计数、最早年龄、截断/新鲜度指标和可离线验证的告警规则;独立采集监听默认关闭,固定指标目录拒绝动态标签。仍需受理/授权/完成阶段延迟与持久吞吐、流程推进延迟、重试/核查/恢复量、全局发送队列、多节点聚合及生产采集/通知验证。
3. 已补齐受保护管理环境中的固定凭据操作文件、轮换、撤销、幂等回执和脱敏管理审计;轮换保留授权绑定并要求新令牌重新建立会话,撤销允许在停用范围内执行且不改写历史记录。仍需补齐提交不明故障切点、多节点安全重绑演练、凭据最小权限配置核对和生产密钥托管/审计演练。
4. 实现保留/归档与受保护记录核对,再执行备份恢复、兼容升级和六类容量负载。未确认交付、有效幂等身份、当前/历史执行证据和未终结流程不能被普通清理破坏。生产HA及RPO/RTO继续按实际拓扑验证,不缩减为本机多进程检查。

View File

@@ -2,7 +2,7 @@
- 文档版本:0.2
- 整理日期:2026-09-17
- 阶段:P0–P5平台功能已通过阶段回归;[P4/P5原范围核对](reports/phase-4-5.md)和[首批故障边界](reports/phase-6-fault-boundaries.md)保留证据边界。P6已补进程观测和固定操作文件凭据轮换/撤销;生产积压、阶段延迟、提交不明切点、归档备份、容量与发布交付继续推进,尚未完成全平台生产验收,数据库保持无外键。
- 阶段:P0–P5平台功能已通过阶段回归;[P4/P5原范围核对](reports/phase-4-5.md)和[首批故障边界](reports/phase-6-fault-boundaries.md)保留证据边界。P6已补进程观测、有界业务状态采样和固定操作文件凭据轮换/撤销;生产积压全局聚合、阶段延迟、提交不明切点、归档备份、容量与发布交付继续推进,尚未完成全平台生产验收,数据库保持无外键。
- 适用范围:Orbit 统一平台,包含 Pulse 任务调度模块、Weave 流程编排模块与公共能力。平台面向多个业务系统复用。
## 阅读顺序

View File

@@ -1,6 +1,6 @@
# 运行指标与告警接入
状态:P6第一批进程观测已实现,指标、采集入口和下方规则均有回归。任务/流程的持久积压和业务阶段延迟仍待补齐;完整生产观测尚未验收。
状态:P6第一批进程观测及有界业务状态采样已实现,指标、采集入口和下方规则均有回归。采样只提供每节点有限快照,完整生产观测尚未验收。
## 1. 启用独立采集端口
@@ -25,7 +25,7 @@ curl -fsS http://127.0.0.1:9090/metrics
仅 `GET /metrics`(及标准HEAD)提供采集,查询参数返回400。正文使用[Prometheus文本格式0.0.4](https://prometheus.io/docs/instrumenting/exposition_formats/),Content-Type为 `text/plain; version=0.0.4; charset=utf-8`,Cache-Control为no-store。输出是本节点的运行快照,没有跨节点或跨指标原子快照保证。
每节点同时最多2个采集请求,超出返回503及 `Retry-After: 1`,不排无限等待队列。独立HTTP服务器的读头/读/写/空闲超时分别为2/3/5/15秒,头部限制8 KiB。采集只访问进程内存,不查询业务表;DB池快照在启动时及之后每5秒读取 `database/sql.DBStats`,该调用不执行SQL。
每节点同时最多2个采集请求,超出返回503及 `Retry-After: 1`,不排无限等待队列。独立HTTP服务器的读头/读/写/空闲超时分别为2/3/5/15秒,头部限制8 KiB。每次HTTP采集只访问进程内存,不查询业务表;DB池快照在启动时及之后每5秒读取 `database/sql.DBStats`,该调用不执行SQL。指标启用后同一个5秒后台采样器另外执行一次有界业务快照:查询固定状态、固定表和固定索引,单状态最多读取10000条,数据库调用使用900ms截止时间;失败只增加错误/超时计数并保留上次成功值,不改变业务事务。
所有指标名称、类型、标签名和取值在代码目录中固定。未知名称、错误类型、非法标签、非有限数值和计数器倒退会被丢弃,并增加 `orbit_observability_rejected_samples_total`。新增指标需要修改目录和回归,不允许业务方动态注册标签。HTTP标签为8种方法、12种路由分类和6种状态分类,两组HTTP族各最多576种标签组合。禁止将任务/流程/租户ID、业务键、URL、参数、原始错误或凭据写入指标。
@@ -47,6 +47,16 @@ curl -fsS http://127.0.0.1:9090/metrics
| `orbit_db_connections_open` / `orbit_db_connections_in_use` / `orbit_db_connections_idle` | gauge | 本节点MySQL连接池当前连接数 |
| `orbit_db_connections_max_open` | gauge | 池配置的最大连接数 |
| `orbit_db_wait_count_total` / `orbit_db_wait_duration_seconds_total` | counter | 连接池累计等待次数/秒数,不是数据库锁等待 |
| `orbit_pulse_tasks_state{state}` | gauge | Pulse任务固定状态的有界计数;单状态达到10000时只保留上限并置截断标记 |
| `orbit_pulse_tasks_oldest_age_seconds` | gauge | WAITING/LEASED/RUNNING/NEEDS_REVIEW样本中最早可处理时间的年龄 |
| `orbit_result_deliveries_state{state}` | gauge | 结果交付固定状态的有界计数 |
| `orbit_result_delivery_oldest_age_seconds` | gauge | PENDING/LEASED交付样本中最早可处理时间的年龄 |
| `orbit_weave_workflows_state{state}` | gauge | Weave实例固定状态的有界计数 |
| `orbit_weave_workflow_oldest_age_seconds` | gauge | RUNNING/WAITING/CANCELLING/NEEDS_REVIEW实例样本中最早更新时间的年龄 |
| `orbit_business_snapshot_total{outcome}` | counter | 有界业务快照成功、错误或超时次数 |
| `orbit_business_snapshot_duration_seconds` | histogram | 有界业务快照耗时;包含数据库读取 |
| `orbit_business_snapshot_last_success_timestamp_seconds` | gauge | 最近一次完整成功快照的Unix时间;失败不会推进 |
| `orbit_business_snapshot_truncated` | gauge | 任一固定状态达到10000上限时为1,否则为0 |
| `orbit_process_start_time_seconds` / `orbit_process_uptime_seconds` | gauge | 本次指标注册器初始化Unix时间/单调时钟经过的秒数;初始化发生在数据库启动校验之后 |
| `orbit_go_goroutines` | gauge | Go协程数,按5秒采样 |
| `orbit_build_info` | gauge | 恒为1,go_version仅取当前编译运行时版本;不是Orbit发布版本 |
@@ -73,11 +83,13 @@ scrape_configs:
示例地址仅适用于同机采集;远程采集需替换为受保护的内部目标。平台运行不依赖采集器、Prometheus或额外数据库。
[五条告警规则](../../deploy/monitoring/orbit.rules.yml)和[离线规则测试](../../deploy/monitoring/orbit.rules.test.yml)包含以下场景:
[七条告警规则](../../deploy/monitoring/orbit.rules.yml)和[离线规则测试](../../deploy/monitoring/orbit.rules.test.yml)包含以下场景:
- 目标连续2分钟采集失败:检查指标监听、网络和进程,不直接判断业务任务停止。
- 启动60秒后,某后台组件超过30秒没有成功批次并持续1分钟:结合readiness、批次错误和数据库状态调查。
- 批次错误速率持续为正2分钟:查日志和原任务/流程审计,不把数据库故障改判成业务失败。
- 有界业务快照连续没有成功超过30秒(启动宽限60秒):检查采样超时/错误和MySQL健康;已有状态值可能已经陈旧。
- 固定状态采样连续达到10000条上限5分钟:状态指标只是有限样本,转用权威数据库查询并进行容量核查。
- 池累计等待时间增长超过0.1秒/秒并持续5分钟:联查锁等待、慢SQL、CPU和存储,不自动提高连接数。
- 内部非法指标更新持续出现:检查观测代码契约,不能忽略丢弃的样本。
@@ -88,4 +100,4 @@ promtool check rules deploy/monitoring/orbit.rules.yml
promtool test rules deploy/monitoring/orbit.rules.test.yml
```
HTTP失败率和延迟可按route/status_class统计;受理接口响应成功与已完成业务应分别判断。可靠结果量、排队/授权/完成延迟、流程Inbox积压、发送队列、磁盘/复制等仍须补充专门指标;具体当前证据见[验证报告](../reports/phase-6-observability.md)。
HTTP失败率和延迟可按route/status_class统计;受理接口响应成功与已完成业务应分别判断。业务状态指标是本节点有限样本,不能相加作为全局精确数量;应结合 `orbit_business_snapshot_last_success_timestamp_seconds` 和 `orbit_business_snapshot_truncated` 判断新鲜度与完整性。可靠结果量、排队/授权/完成阶段延迟、流程Inbox推进延迟、发送队列、磁盘/复制等仍须补充专门指标;具体当前证据见[进程观测报告](../reports/phase-6-observability.md)和[有界业务采样报告](../reports/phase-6-business-observability.md)。

View File

@@ -0,0 +1,24 @@
# P6:有界业务状态采样
日期:2026-09-18。本文记录第二批运行观测实现的边界和回归证据。它补充进程级批次指标,用于回答“本节点看到哪些固定状态、最早样本等待多久、采样是否完整”,不把有限样本当作全局业务统计,也不宣称生产容量或高可用已经验收。
## 已实现
- 迁移 `000026_operational_metrics` 为 `pulse_tasks`、`orbit_deliveries`、`weave_instances` 增加固定前缀索引;不增加模型字段,不引入外键或级联。
- [存储采样器](../../internal/storage/mysql/operational_metrics.go)只拼接代码内固定的表、索引、列名和状态集合。每个状态使用索引读取最多10001条,再将结果封顶到10000;至少一类封顶时 `orbit_business_snapshot_truncated=1`。
- 采样器先读取数据库UTC时间,再读取任务、结果交付和流程实例固定状态计数及最早未完成年龄。所有调用由独立900ms上下文限制;取消、数据库错误和超时都返回失败,不修改持久化数据。
- [业务指标记录器](../../internal/observability/business.go)将成功、错误、超时分别计数并记录耗时。失败样本不覆盖最后一次成功状态,同时保留最后成功时间,方便告警区分“旧值可见”和“本轮采集失败”。标签基数和状态取值均在目录中固定。
- [进程入口](../../cmd/orbit/main.go)仅在显式启用指标时每5秒后台采样;`GET /metrics`仍只渲染进程内存,不在抓取请求中执行SQL。采样错误进入脱敏结构化日志,不能改变任务、交付或流程事务。
## 回归证据
- [业务记录器单测](../../internal/observability/metrics_test.go)验证成功状态、年龄、截断、成功计数和失败后保留最后成功值;超时计数单独增加。
- [真实MySQL专项](../../internal/storage/mysql/operational_metrics_integration_test.go)验证迁移索引真实存在、数据库外键为0、任务状态被采样、固定状态集合存在、空交付/流程状态不误报,并验证已取消上下文被拒绝。
- `go test ./...`覆盖编译和普通单测;真实MySQL专项由标准`GO=... DOCKER=... sh scripts/test-mysql.sh`执行,未设置`ORBIT_TEST_MYSQL_DSN`时专项会跳过,不能把跳过当通过。最终标准脚本在Go 1.27.1、darwin/arm64、Docker MySQL 8.4.10环境退出码为0;其中存储/迁移/事务组256.539秒,指标开关进程组5.204秒,流程运行器全停恢复49.333秒,SDK与两个独立业务示例均通过。专项日志确认`TestIntegrationOperationalSnapshot`、`TestIntegrationNoForeignKeysUpgrade`、`TestIntegrationCredentialOperations`及`TestIntegrationCredentialCommitFaults`均PASS。
- 当前固定目录导出的指标夹具为929159字节,`promtool check metrics`成功;`promtool check rules deploy/monitoring/orbit.rules.yml`报告7条规则成功,`promtool test rules deploy/monitoring/orbit.rules.test.yml`成功。标准验证镜像仅用于离线检查,平台运行不依赖Prometheus。
## 解释和边界
每个Orbit节点都读取自己的有限样本;多节点指标不能直接相加获得全局精确积压。达到10000上限、采样超时、节点重启或节点间时间不同都会影响解释,必须结合截断标记、最后成功时间、数据库权威查询和审计判断。最早年龄使用任务/交付的`available_at`及流程的`updated_at`,它是告警线索,不是端到端受理、授权或完成延迟。
当前仍未完成持久化吞吐与阶段延迟、流程Inbox推进延迟、重试/核查/恢复量、发送队列全局聚合、生产采集通知演练、锁/磁盘/复制指标和多故障域容量验证。此批实现不能替代保留、备份恢复、HA、RPO/RTO及发布验收。

View File

@@ -1,6 +1,6 @@
# P6:进程指标、采集隔离与告警规则
日期:2026-09-18。范围为运行观测第一批,交付HTTP/WS、连接池、后台批次、进程指标和可离线验证的告警规则。P6仍在进行,任务/流程持久积压和阶段延迟没有被本批替代。
日期:2026-09-18。范围为运行观测第一批,交付HTTP/WS、连接池、后台批次、进程指标和可离线验证的告警规则。本文记录第一批完成时的迁移版本25;后续000026有界业务状态采样见[专项报告](phase-6-business-observability.md)。P6仍在进行,完整生产观测没有被任一批次替代。
## 实现和边界
@@ -24,7 +24,7 @@
## 独立格式与规则验证
全量有限HTTP组合的文本夹具为926666字节,使用本地已有官方promtool 3.5.0(linux/arm64,revision 8be3a9560fbdd18a94dedec4b747c35178177202)执行`check metrics`,退出0且无格式/命名告警。固定验证镜像摘要为`prom/prometheus@sha256:63805ebb8d2b3920190daf1cb14a60871b16fd38bed42b857a3182bc621f4996`,运行时关闭网络;此版本仅描述实际验证器,不是生产部署版本建议。
第一批全量有限HTTP组合的文本夹具为926666字节,使用本地已有官方promtool 3.5.0(linux/arm64,revision 8be3a9560fbdd18a94dedec4b747c35178177202)执行`check metrics`,退出0且无格式/命名告警。固定验证镜像摘要为`prom/prometheus@sha256:63805ebb8d2b3920190daf1cb14a60871b16fd38bed42b857a3182bc621f4996`,运行时关闭网络;此版本仅描述实际验证器,不是生产部署版本建议。当前新增业务状态目录的夹具和校验见专项报告。
五条告警规则通过`check rules`;[规则测试](../../deploy/monitoring/orbit.rules.test.yml)通过`test rules`,验证目标失联、启动宽限、组件停滞、健康不报警、错误/等待/非法采样触发及恢复后的解除。