第 43 章 / 共 51 章
卷五 · 扩展、运维与实战
运维与观测:让服务自己会说话
没有管理后台(第 1 章的坑)不等于没有观测——它意味着观测是你的应用代码的一部分。本章给出三支柱的 XServer 做法。
本章导读
站位:ch06 排错手册的运营版。产出物:结构化日志体系、内存报告开关、/health 与 /stats 巡检路由——直接搬进你的 modules/。
43.1 引入
观测的三个问题:服务活着吗(健康)、服务干了什么(日志)、服务还健康吗(资源趋势)。XServer 语境下它们都有极短路径:健康 = 一个路由;日志 = xrtLogger(76 个 API,分级/格式化/多输出)或 printf;资源 = 内存报告 + RSS 采样。重要的是从第一天就装上,而不是出事再补。
43.2 结构化日志
从 printf 到 logger
/* 开发期:printf 足够(demo 的做法)*/
printf("[demo] handler done: %s\n", sPath);
/* 运营期:xrtLogger —— 分级、多输出、可接管 */
/* Init 时建 logger(文件 + stdout 双输出,级别可配)*/
G_pLog = xrtLoggerCreate(...);
/* 请求路径:带级别与模块标签 */
xrtLogInfo(G_pLog, "api", "item %lld fetched in %lld us", iId, iUs);
xrtLogWarn(G_pLog, "api", "slow query: %lld us", iUs);
/* ServiceUnit 里销毁——日志器也是代的状态 */
- 级别纪律:INFO 记正常流转(可关)、WARN 记可自动恢复的异常、ERROR 记需要人看的事
- 请求 ID:在模块层生成短 ID 贯穿一条请求的全部日志——排错时的"串联线索"
- 输出:stdout 进 journald/服务管理器;文件输出自己轮转(或交给 logrotate 按尺寸切)
43.3 内存观测
- 外部趋势:RSS 采样(drill 的方式:PowerShell WorkingSet64 / /proc VmRSS)进监控——平线是健康,斜线要查
- 内部结构:xrt 内存调试体系(canary / UAF / 分配报告,TEXT 与 JSON 双格式)——在宿主构建配置开启(见 xrt 教程 ch06),生产按需开关
- 换代对账:finalize 计数(ch30)+ 报告的活动分配数,是"热重载零泄漏"的日常证据
43.4 巡检路由
/health 与 /stats(模式)
/* /health:给负载均衡与监控的极简端点 */
ReplyText(pReq, 200, "ok"); /* 复杂逻辑免谈 */
/* /stats:应用级指标(鉴权后)*/
xvalue* p = xrtValueObject();
xrtValueObjectSetNew(p, "uptime_s", xrtValueInt64(UpSec()));
xrtValueObjectSetNew(p, "requests", xrtValueInt64((int64)G_iTotal));
xrtValueObjectSetNew(p, "ws_online", xrtValueInt64(ConnCount()));
xrtValueObjectSetNew(p, "reload", ReloadSummary()); /* 终态计数 */
ReplyJSON(pReq, 200, p); xrtValueRelease(p);
模式要点:/health 只报生死(挂了依赖检查会让 LB 误杀);/stats 报业务指标并挡在鉴权后(ch27 的纪律)。要不要 Prometheus 格式?xvalue → 文本一行循环的事。
43.5 契约
- 支柱线:健康路由、结构化日志、资源趋势——第一天就装。
- 纪律线:/health 极简;/stats 鉴权;日志级别三分。
- 基线线:测试与演练(func/drill/routebench)在版本演进中持续跑——它们是行为回归的对照。
常见错误
/health 里查数据库
- 症状
- 数据库抖一下,LB 把所有实例摘除——全站雪崩。
- 原因
- 把"深度体检"混进了"生死探针"。LB 探针只答"进程能不能服务";依赖健康放单独的 /deep(人看或告警看)。
日志无 ID 串联
- 症状
- 并发下日志交错,无法还原一次请求的轨迹。
- 原因
- 裸 printf 没有请求上下文。模块层生成短 ID 并带进每条日志(43.2 的请求 ID 纪律)。
编程练习
基础三支柱装齐
给 demo 加 /health、/stats、xrtLogger 化的请求日志。
验收:/health <1ms;/stats 需令牌;日志可按请求 ID 过滤。
进阶趋势采集
外部脚本每 10s 采 RSS + /stats,落 CSV 画图。
验收:跑一次 10 次换代的压力段,曲线平稳可判读。
挑战Prometheus 文本端点
实现 /metrics:从注册表导出 ws_online、请求计数、换代计数等指标。
验收:Prometheus 抓取成功并能画最小仪表盘。
基础三支柱装齐
给 demo 加 /health、/stats、xrtLogger 化的请求日志。
验收:/health <1ms;/stats 需令牌;日志可按请求 ID 过滤。
进阶趋势采集
外部脚本每 10s 采 RSS + /stats,落 CSV 画图。
验收:跑一次 10 次换代的压力段,曲线平稳可判读。
挑战Prometheus 文本端点
实现 /metrics:从注册表导出 ws_online、请求计数、换代计数等指标。
验收:Prometheus 抓取成功并能画最小仪表盘。
小结
| 要点 | 结论 |
|---|---|
| 三支柱 | /health(生死)、日志(轨迹)、资源趋势(健康度) |
| 日志 | 开发 printf / 运营 xrtLogger;请求 ID 串联 |
| 内存 | RSS 趋势外部采;分配报告内部对账 |
| 巡检 | health 极简、stats 鉴权、deep 分离 |
本章涉及的 API 参考
xrt 延伸阅读
- xrt 参考 · logger — 分级 / 格式化 / 多输出的完整 API
- xrt 参考 · memory_stats — 分配统计快照