2. Azure Monitor与Application Insights实战

Azure Monitor 是 Azure 上统一的监控数据平面,Application Insights 则是面向应用层的 APM 能力。两者组合后,可以覆盖从平台指标到应用依赖、从单条请求到跨服务事务的完整观测链路。本节围绕四个关键动作展开:指标如何采集、日志如何查询、端到端事务如何追踪、性能基线如何建立。

一、指标采集:平台指标与应用指标的分工

Azure Monitor 的指标分为两类。第一类是平台指标,由 Azure 资源提供程序自动上报,例如虚拟机的 CPU 百分比、App Service 的 Http5xx 计数、SQL Database 的 DTU 消耗、存储账户的 Transactions。这类指标无需埋点,默认按分钟级聚合,保留期通常为 93 天,适合做容量趋势和告警。第二类是应用指标,由 Application Insights SDK 采集,例如请求速率、失败率、依赖调用时长、异常计数,粒度更细,可下钻到操作名和依赖目标。

采集链路可以概括为:应用 SDK 产生遥测 → 通过连接字符串写入 Application Insights 资源 → Azure Monitor 统一存储与查询。连接字符串包含 InstrumentationKey 和 IngestionEndpoint,是 SDK 与资源之间的唯一绑定凭据。对于 .NET 应用,典型配置如下:

{
  "ApplicationInsights": {
    "ConnectionString": "InstrumentationKey=xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx;IngestionEndpoint=https://chinaeast2-0.in.applicationinsights.azure.cn/"
  }
}

采样是采集阶段最容易被忽视的参数。默认自适应采样会按每秒请求量动态调整,可能让指标与真实请求数产生偏差。若用于容量治理,建议对关键业务操作设置固定采样率,或在查询时用 itemCount 还原真实数量。此外,Live Metrics 提供秒级实时流,适合发布观察;而标准指标有 1~5 分钟延迟,不适合做瞬时判断。

二、日志查询:KQL 是核心工具

Application Insights 的日志存储在 Log Analytics 工作区中,使用 KQL 查询。常用的表包括 requests(请求)、dependencies(依赖)、exceptions(异常)、traces(跟踪)、pageViews(页面浏览)。查询的基本结构是“表 → 过滤 → 聚合 → 排序”。

例如,统计过去 1 小时各操作的失败率:

requests
| where timestamp > ago(1h)
| summarize Total = count(), Failed = countif(success == false) by name
| extend FailureRate = round(100.0 * Failed / Total, 2)
| order by FailureRate desc

再如,找出 P95 响应时间最慢的依赖调用:

dependencies
| where timestamp > ago(24h)
| summarize P95 = percentile(duration, 95) by target, name
| order by P95 desc
| take 10

查询时要注意时间范围与采样。若开启了采样,count() 得到的是采样后条数,应改用 sum(itemCount)。另外,union 可以把 requests 与 dependencies 合并分析,join 可以按 operation_Id 关联请求与依赖,这是端到端追踪的查询基础。

三、端到端事务追踪:operation_Id 串联全链路

Application Insights 为每次入口请求分配一个 operation_Id,同一事务内的所有遥测项共享该 ID。请求本身是 operation_Name 的根,依赖调用、异常、跟踪都挂在同一 operation_Id 下。跨服务时,通过 Request-Id 和 Correlation-Context 头传递关联信息,形成分布式追踪。

排查一次慢请求的典型路径是:先在 requests 表按 operation_Id 定位根请求,再用同一 ID 查询 dependencies 和 exceptions,按时间排序还原调用顺序。下面的 SVG 展示了这一事务追踪的信号链结构。

端到端事务追踪:operation_Id 串联请求、依赖与异常 客户端请求 operation_Id = A1B2 API 入口请求 requests · 根操作 业务处理与依赖调用 dependencies · SQL / HTTP / Redis 异常与跟踪 exceptions · traces · 同一 operation_Id 跨服务关联 Request-Id · Correlation-Context KQL 还原调用链 requests | where operation_Id == "A1B2" | union dependencies, exceptions, traces | project timestamp, itemType, name, duration, success | order by timestamp asc

图中可以看到,一次事务从客户端请求进入 API,operation_Id 作为贯穿标识,把 requests、dependencies、exceptions、traces 四类遥测统一到同一时间线上。跨服务调用则通过 Request-Id 头继续传递关联。查询时用 union 合并多表并按 timestamp 排序,即可还原完整调用顺序。

四、性能基线建立:从数据到判断标准

性能基线不是单一数字,而是一组随时间稳定的参考区间。建立基线通常分三步:选指标、定窗口、算分位。指标应选与用户体验直接相关的,例如请求响应时间、依赖调用时长、失败率、吞吐量。窗口建议覆盖至少 7 天,包含工作日与周末,避免把发布日或大促日混入基线。

分位数比平均值更适合做基线。平均值会被少量极慢请求拉高,而 P50、P95、P99 能分别反映典型体验、多数用户上限和尾部风险。例如,某 API 过去 7 天的 P50 为 120ms、P95 为 480ms、P99 为 1.2s,那么可以把 P95 作为告警阈值参考,把 P99 作为容量治理的重点观察对象。

基线建立后,需要持续对比。常用做法是用 KQL 计算当前窗口与基线窗口的偏差:

let baseline = requests
| where timestamp between (ago(8d) .. ago(1d))
| summarize BaseP95 = percentile(duration, 95) by name;
requests
| where timestamp > ago(1h)
| summarize CurP95 = percentile(duration, 95) by name
| join kind=inner baseline on name
| extend Deviation = round(100.0 * (CurP95 - BaseP95) / BaseP95, 1)
| where abs(Deviation) > 20

当偏差超过 20% 时触发关注,再结合依赖耗时、异常率和部署记录判断是回归还是正常波动。基线不是一次性的,每次重大发布、架构调整或流量模型变化后都应重新校准。

指标采集关注“有没有数据”,日志查询关注“数据说明什么”,端到端追踪关注“问题发生在哪一段”,性能基线关注“当前是否偏离正常”。四者形成从采集到判断的闭环。
采样会同时影响指标和日志。若用 count() 统计请求数,采样开启时结果会偏小,应改用 sum(itemCount)。做容量治理时,建议对关键操作关闭自适应采样或固定采样率。

把四步串起来,一个可复用的实践顺序是:先用平台指标确认资源层是否异常,再用 Application Insights 指标定位应用层异常操作,接着用 operation_Id 查询还原事务链路,最后与性能基线对比判断是否需要干预。这样既避免盲目扩容,也能让容量治理有据可依。