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 @@
# 运行指标与告警接入
状态: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)。