Files
orbit/docs/api/observability.md

13 KiB
Raw Blame History

运行指标与告警接入

状态:P6第一批进程观测、有界业务状态采样和固定事件窗口采样已实现,指标、采集入口和下方规则均有回归。采样只提供每节点有限快照,完整生产观测尚未验收。

1. 启用独立采集端口

默认不启动指标监听,也不创建指标注册器。显式配置后,业务端口与采集端口分别监听:

export ORBIT_HTTP_ADDR=127.0.0.1:8080
export ORBIT_METRICS_ADDR=127.0.0.1:9090
# 数据库凭据按现有秘密配置注入;先完成迁移。
go run ./cmd/orbit
curl -fsS http://127.0.0.1:9090/metrics

ORBIT_METRICS_ADDR 为空或未设置即关闭,127.0.0.1:0 可用于测试时分配空闲端口。非法地址、端口超界或绑定失败会拒绝启动;绑定失败不能静默降级为“看起来已经监控”。进程日志用 metrics_address 报告实际采集地址。业务端口 /metrics 返回404;指标端口不注册业务或健康接口。

指标监听不使用业务凭据,没有多租户查询接口;只面向平台运维人员。部署到远程采集网络时,显式选择内部地址并配置网络策略或带鉴权/TLS的内部代理,不将此端口发布到公网。SDK不封装该端点;业务读取、核查和审计仍使用原有鉴权API。

2. HTTP契约和数据范围

仅 GET /metrics(及标准HEAD)提供采集,查询参数返回400。正文使用Prometheus文本格式0.0.4,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。每次HTTP采集只访问进程内存,不查询业务表;DB池快照在启动时及之后每5秒读取 database/sql.DBStats,该调用不执行SQL。指标启用后同一个5秒后台采样器另外执行一次有界业务快照:查询固定状态、固定表和固定索引,单状态或事件类别最多读取10000条;固定事件类别窗口为最近5分钟;数据库调用使用900ms截止时间;失败只增加错误/超时计数并保留上次成功值,不改变业务事务。

所有指标名称、类型、标签名和取值在代码目录中固定。未知名称、错误类型、非法标签、非有限数值和计数器倒退会被丢弃,并增加 orbit_observability_rejected_samples_total。新增指标需要修改目录和回归,不允许业务方动态注册标签。HTTP标签为8种方法、12种路由分类和6种状态分类,两组HTTP族各最多576种标签组合。禁止将任务/流程/租户ID、业务键、URL、参数、原始错误或凭据写入指标。Worker/Event连接上限、Hub领取协程数和内存排队槽位也以固定基数导出,便于核对节点实际生效的背压边界。

格式化输出前只短暂复制注册器引用;不在全局记录锁下排序、格式化或写网络。直方图的桶、count、sum在同一局部锁下获取,保持单条直方图快照一致。指标在重启后重置,不能用于账务审计、幂等判断或恢复授权。

3. 指标目录

名称 类型 口径
orbit_http_requests_total counter HTTP响应完成次数;成功WS握手在Hijack完成时计入
orbit_http_request_duration_seconds histogram HTTP处理/升级握手耗时,不包含成功升级后的连接存续时间
orbit_http_requests_in_flight gauge 尚未返回或成功升级的HTTP处理器数量
orbit_http_panics_total counter 非正常返回的HTTP处理器次数;无响应时按5xx观测分类,但不声称客户端收到500;保留原panic传播及已发响应
orbit_websocket_connections gauge 成功升级且处理器尚未退出的WS连接,按worker_connect/event_connect区分
orbit_websocket_connections_total counter WS成功升级累计次数;并不表示协议hello、业务鉴权或任务执行成功
orbit_runtime_batch_total counter 后台批次返回次数,标签component及outcome
orbit_runtime_batch_duration_seconds histogram 后台批次调用耗时,标签component
orbit_runtime_batch_last_success_timestamp_seconds gauge 最后一次无错误批次返回的Unix时间;启动后未成功时为0
orbit_runtime_tick_interval_seconds{component} gauge 节点实际生效的后台扫描间隔,component为workflow、schedule、execution_recovery
orbit_runtime_batch_limit gauge 节点实际生效的后台批量上限
orbit_shutdown_timeout_seconds gauge 节点实际生效的排空与优雅关闭窗口(秒)
orbit_worker_connection_limit gauge 节点实际生效的 Worker WebSocket 连接上限
orbit_event_connection_limit gauge 节点实际生效的 Event WebSocket 连接上限
orbit_dispatch_workers gauge 每个 WebSocket Hub 同时执行数据库领取调用的协程上限
orbit_dispatch_capacity gauge 每个 WebSocket Hub 领取调用的有界内存排队槽位
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_db_transaction_retries_total counter 本进程提交前因 MySQL 1205/1213 实际执行的事务重试次数;不包含 Begin/Commit 错误或提交回执不明
orbit_db_transaction_retry_exhausted_total counter 本进程提交前因 MySQL 1205/1213 达到最多两次重试上限的事务次数;需要结合原操作身份和数据库锁观测核查
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_weave_inbox_state{state} gauge Weave内部Inbox固定状态的有界计数,状态为PENDING、LEASED、PROCESSED、QUARANTINED
orbit_weave_inbox_oldest_age_seconds gauge PENDING/LEASED Inbox样本中最早可处理时间的年龄
orbit_business_events_recent{event} gauge 最近5分钟内固定事件类别的有界数量,用于观察受理、完成、核查、恢复和流程推进趋势
orbit_pulse_task_terminal_latency_seconds / _max_seconds gauge 最近5分钟终态任务从创建到完成的平均/最大耗时样本,单位秒
orbit_weave_workflow_terminal_latency_seconds / _max_seconds gauge 最近5分钟终态流程从创建到完成的平均/最大耗时样本,单位秒
orbit_pulse_task_accept_to_start_latency_seconds / _max_seconds gauge 最近5分钟同时采到 task.accepted 与 task.started 的任务受理到开始平均/最大耗时样本,单位秒
orbit_pulse_task_accept_to_terminal_latency_seconds / _max_seconds gauge 最近5分钟同时采到任务受理与确定终态事件的平均/最大耗时样本,单位秒
orbit_weave_workflow_start_to_terminal_latency_seconds / _max_seconds gauge 最近5分钟同时采到 workflow.started 与 workflow.stopped 的流程开始到停止平均/最大耗时样本,单位秒
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_process_draining gauge 节点是否正在优雅排空;0为服务中,1为排空中
orbit_go_goroutines gauge Go协程数,按5秒采样
orbit_build_info{go_version,version,revision} gauge 恒为1,导出当前Go版本、发布版本和源码提交;构建时间及完整协议身份通过 /version 获取
orbit_observability_rejected_samples_total counter 内部不合法指标更新次数,正常运行应为0

HTTP方法为GET/POST/PATCH/PUT/DELETE/HEAD/OPTIONS/OTHER;路由为health_live、health_ready、worker_connect、event_connect、tasks、queues、workflows、workflow_definitions、schedules、subscriptions、application_resources、other;状态为1xx–5xx及other。路径值不会进入标签;分类不表示路由存在或授权通过。独立采集请求不混入业务HTTP计数。

后台component为workflow、schedule、execution_recovery;outcome为success、error、cancelled。context.Canceled归cancelled,超时与其他错误归error,错误文本不导出。success只说明一批调用无错误返回,允许空批次;不能将它解释为持久任务成功量。已提交但确认不明的状态仍须按原身份核对。

直方图有限桶边界固定为0.005、0.01、0.025、0.05、0.1、0.25、0.5、1、2.5、5、10秒,另有+Inf桶和sum/count。不得将高于10秒的有限分位估计当作精确延迟,后续容量验证需结合样本及合适的桶配置。

4. 采集与告警例子

如果已有兼容采集器,可配置job名为orbit(规则按此名筛选):

scrape_configs:
  - job_name: orbit
    scrape_interval: 15s
    scrape_timeout: 3s
    static_configs:
      - targets: ["127.0.0.1:9090"]

示例地址仅适用于同机采集;远程采集需替换为受保护的内部目标。平台运行不依赖采集器、Prometheus或额外数据库。

八条告警规则和离线规则测试包含以下场景:

  • 目标连续2分钟采集失败:检查指标监听、网络和进程,不直接判断业务任务停止。
  • 启动60秒后,某后台组件超过30秒没有成功批次并持续1分钟:结合readiness、批次错误和数据库状态调查。
  • 批次错误速率持续为正2分钟:查日志和原任务/流程审计,不把数据库故障改判成业务失败。
  • 有界业务快照连续没有成功超过30秒(启动宽限60秒):检查采样超时/错误和MySQL健康;已有状态值可能已经陈旧。
  • 固定状态采样连续达到10000条上限5分钟:状态指标只是有限样本,转用权威数据库查询并进行容量核查。
  • 池累计等待时间增长超过0.1秒/秒并持续5分钟:联查锁等待、慢SQL、CPU和存储,不自动提高连接数。
  • 提交前 MySQL 事务重试达到有界上限:检查锁等待、死锁和原操作身份,不按告警盲目重放;提交回执不明不计入此规则。
  • 内部非法指标更新持续出现:检查观测代码契约,不能忽略丢弃的样本。

这些阈值是可修改的运行基线,尚未通过生产负载调优;不构成SLO或可用性承诺。规则测试覆盖触发、启动宽限、健康不报警和错误停止后的解除,未发送实际通知或创建外部监控服务。

promtool check rules deploy/monitoring/orbit.rules.yml
promtool test rules deploy/monitoring/orbit.rules.test.yml

HTTP失败率和延迟可按route/status_class统计;受理接口响应成功与已完成业务应分别判断。业务状态、事件窗口、Inbox状态和终结耗时指标是本节点有限样本,不能相加作为全局精确数量;未知事件类型不会进入标签,终结耗时从持久化created_at到completed_at计算,不包含端到端外部副作用,Inbox年龄从available_at计算,不等于流程推进完成延迟。应结合 orbit_business_snapshot_last_success_timestamp_seconds 和 orbit_business_snapshot_truncated 判断新鲜度与完整性。可靠结果量、授权阶段延迟、全局发送队列、磁盘/复制等仍须补充专门指标;具体当前证据见进程观测报告和有界业务采样报告。