指标日志链路三位一体:华为云 AOM/APM 全链路监控实战
💡 摘要: 本系列第 5 篇!基于 CCE 上运行的 Java 微服务,深入配置华为云 AOM 监控大盘、APM 调用链追踪、LTS 日志采集、自定义告警规则,构建"指标+日志+链路"三位一体的可观测性体系。涵盖 APM Agent 接入、JVM 监控看板、业务埋点、智能告警配置、真实故障排查案例,附 8 个实用监控模板和 3 个踩坑实录。
🎯 为什么需要全链路监控?
云原生实战系列回顾

应用上线 ≠ 万事大吉。没有监控的应用就像蒙眼开车,第4篇部署的应用上线后,你需要知道:
- 接口响应慢了?是 SQL 慢查还是网络抖动?
- 内存泄漏了?哪个类加载器在作祟?
- 业务异常飙升?是代码 Bug 还是依赖故障?
华为云可观测性三件套
| 维度 | 华为云产品 | 解决什么问题 | 类比 |
|---|---|---|---|
| 📊 指标 | AOM(应用运维管理) | CPU/内存/磁盘/网络/请求量 | 体温计 |
| 🔗 链路 | APM(应用性能管理) | 请求调用链、依赖关系、慢调用 | CT 扫描 |
| 📝 日志 | LTS(云日志服务) | 错误堆栈、业务日志、审计日志 | 病历本 |
🏗️ 架构设计:AOM/APM/LTS 集成架构

📊 第一步:AOM 指标监控(基础层)
1.1 AOM 是什么?
AOM(Application Operations Management) 是华为云的一站式监控平台,免费提供 CCE 集群的基础监控:
- ✅ 自动接入:CCE 集群创建后自动对接 AOM,零配置
- ✅ 开箱即用:提供 30+ 预置监控大盘
- ✅ 多维度:集群、节点、Pod、容器、应用的逐层下钻
1.2 查看预置监控大盘
# 方式一:控制台
# 登录华为云 → AOM → 监控大盘 → CCE 集群监控
# 预置大盘包括:
# - 集群总览(CPU/内存/网络/磁盘)
# - 节点监控(每个节点的资源使用率)
# - Pod 监控(每个 Pod 的资源使用率)
# - 容器监控(每个容器的详细指标)
# 方式二:AOM API 查询
curl -X GET "https://aom.cn-north-4.myhuaweicloud.com/v1/{project_id}/api/v1/query" \
-H "X-Auth-Token: $TOKEN" \
--data-urlencode 'query=avg_over_time(cpu_usage{container="demo-app"}[5m])'
1.3 自定义监控大盘
默认大盘不够?创建自定义大盘聚焦核心指标:
# 自定义大盘配置(AOM 控制台操作)
大盘名称: Java 微服务监控看板
行 1:
- 图表: CPU 使用率
指标: cpu_usage{container="demo-app"}
类型: 时序图
聚合: avg by(pod_name)
单位: %
- 图表: 内存使用率
指标: memory_usage{container="demo-app"}
类型: 时序图
聚合: avg by(pod_name)
单位: MB
行 2:
- 图表: 请求速率
指标: container_network_receive_bytes_total{container="demo-app"}
类型: 速率图
单位: bytes/s
- 图表: JVM 堆内存
指标: jvm_heap_memory_used_bytes{application="demo-app"}
类型: 时序图
聚合: sum by(pod_name)
单位: MB
行 3:
- 图表: GC 暂停时间
指标: jvm_gc_pause_seconds_sum{application="demo-app"}
类型: 柱状图
单位: 秒
- 图表: 线程数
指标: jvm_threads_live_threads{application="demo-app"}
类型: 时序图
聚合: sum by(pod_name)
单位: 个
1.4 关键监控指标大全

💡 提示: JVM 指标需要 APM Agent 配合,见第二步。
🔗 第二步:APM 调用链追踪(链路层)
2.1 为什么需要 APM?
当用户投诉"接口很慢",传统监控只能告诉你哪个 Pod 慢了,APM 能告诉你为什么慢:
用户请求 → API Gateway → demo-app → MySQL 查询(500ms,慢查!) → Redis 缓存(2ms) → 返回
↑ 这里慢了!原来是 SQL 没有索引
2.2 安装 APM Agent
APM Agent 以 javaagent 方式注入 JVM,无代码侵入:
# 第一步:下载 APM Agent(在 CCE 节点或本地)
wget https://apm2-cn-north-4.obs.cn-north-4.myhuaweicloud.com/apm-javaagent/apm-javaagent-3.8.0.tar.gz
tar -xzf apm-javaagent-3.8.0.tar.gz
# 解压后得到 apm-javaagent.jar 和配置文件
上传到 SWR 作为 Init Container 镜像,或直接挂载 OBS 对象存储。
2.3 修改 Deployment 配置
apiVersion: apps/v1
kind: Deployment
metadata:
name: demo-app
namespace: default
spec:
replicas: 3
selector:
matchLabels:
app: demo-app
template:
metadata:
labels:
app: demo-app
spec:
# 使用 Init Container 下载 APM Agent
initContainers:
- name: apm-agent-installer
image: swr.cn-north-4.myhuaweicloud.com/demo/tools:busybox
command: [ "sh", "-c", "cp /tmp/apm-javaagent.jar /apm/agent/" ]
volumeMounts:
- name: apm-agent
mountPath: /apm/agent
containers:
- name: demo-app
image: swr.cn-north-4.myhuaweicloud.com/demo/demo-app:latest
env:
# ===== APM 配置 =====
- name: JAVA_TOOL_OPTIONS
value: >
-javaagent:/apm/agent/apm-javaagent.jar
-Dapm.application=demo-app
-Dapm.env=production
-Dapm.agent.service_name=demo-app
-Dapm.collector.address=https://apm.cn-north-4.myhuaweicloud.com
-Dapm.collector.project_id=${PROJECT_ID}
-Dapm.collector.access_key=${APM_AK}
-Dapm.collector.secret_key=${APM_SK}
-Dapm.tracing.enabled=true
-Dapm.tracing.sampling_rate=0.1
-Dapm.jvm.enabled=true
-Dapm.jdbc.enabled=true
-Dapm.redis.enabled=true
-Dapm.http.enabled=true
- name: PROJECT_ID
valueFrom:
secretKeyRef:
name: huawei-cloud-secret
key: project_id
- name: APM_AK
valueFrom:
secretKeyRef:
name: huawei-cloud-secret
key: apm_ak
- name: APM_SK
valueFrom:
secretKeyRef:
name: huawei-cloud-secret
key: apm_sk
volumeMounts:
- name: apm-agent
mountPath: /apm/agent
readOnly: true
volumes:
- name: apm-agent
emptyDir: { }
🔥 踩坑经验 1:
sampling_rate=0.1(10% 采样率)足够生产环境使用。100% 采样会导致 APM 存储爆炸,每天产生 TB 级 Trace 数据。电商大促时建议降到 1-5%。
2.4 创建 APM AccessKey 密钥
# 方式一:控制台创建
# 登录华为云 → 应用性能管理 APM → 应用配置 → AccessKey
# 创建密钥对(AK/SK)
# 方式二:创建 Kubernetes Secret
kubectl create secret generic huawei-cloud-secret \
--from-literal=project_id=your_project_id \
--from-literal=apm_ak=your_apm_ak \
--from-literal=apm_sk=your_apm_sk \
-n default
2.5 APM 监控能力总览
| 监控维度 | 自动采集 | 需要配置 | 典型问题发现 |
|---|---|---|---|
| 调用链追踪 | ✅ HTTP 请求 | 无需配置 | 慢调用、异常调用 |
| JDBC 慢查询 | ✅ MySQL/PostgreSQL | 无需配置 | SQL 全表扫描 |
| Redis 调用 | ✅ Jedis/Lettuce | 无需配置 | 热 Key、大 Value |
| HTTP Client | ✅ RestTemplate/OkHttp | 无需配置 | 外部依赖超时 |
| JVM 监控 | ✅ | apm.jvm.enabled=true |
GC 频繁、内存泄漏 |
| 线程分析 | ✅ | 默认开启 | 死锁、线程阻塞 |
| 自定义埋点 | 手动配置 | @Trace 注解 |
业务自定义链路 |
📝 第三步:LTS 日志管理(日志层)
3.1 配置容器标准输出
CCE 默认采集容器的 stdout/stderr 到 AOM,但不采集日志文件。最佳实践:应用日志全部输出到 stdout:
<!-- logback-spring.xml -->
<configuration>
<!-- 开发环境输出到文件 -->
<springProfile name="dev">
<appender name="FILE" class="ch.qos.logback.core.rolling.RollingFileAppender">
<file>/logs/demo-app.log</file>
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
<fileNamePattern>/logs/demo-app.%d{yyyy-MM-dd}.log</fileNamePattern>
<maxHistory>7</maxHistory>
</rollingPolicy>
<encoder>
<pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n</pattern>
</encoder>
</appender>
</springProfile>
<!-- 生产环境只输出到 stdout(容器日志采集) -->
<springProfile name="prod">
<appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
<!-- JSON 格式输出,方便 LTS 结构化解析 -->
<encoder class="net.logstash.logback.encoder.LogstashEncoder">
<includeContext>false</includeContext>
<customFields>{"app":"demo-app","env":"production"}</customFields>
</encoder>
</appender>
<root level="INFO">
<appender-ref ref="STDOUT"/>
</root>
</springProfile>
</configuration>
3.2 结构化日志格式
JSON 格式日志让 LTS 可以做全文搜索和字段提取:
{
"@timestamp": "2026-04-15T10:30:15.123+08:00",
"level": "ERROR",
"logger": "com.demo.order.OrderService",
"thread": "http-nio-8080-exec-3",
"app": "demo-app",
"env": "production",
"traceId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
"message": "订单支付失败",
"orderId": "ORD20260415001",
"userId": "u_10086",
"amount": 299.00,
"errorType": "PaymentTimeoutException",
"duration": 5032,
"stackTrace": "com.demo.order.PaymentTimeoutException: 支付超时\n\tat com.demo.order.OrderService.pay(OrderService.java:85)\n..."
}
优点: Logstash Encoder 自动注入 traceId,串联 APM 调用链和日志,一键跳转。
3.3 添加 Maven 依赖
<dependency>
<groupId>net.logstash.logback</groupId>
<artifactId>logstash-logback-encoder</artifactId>
<version>7.4</version>
</dependency>
3.4 LTS 日志采集配置
# LTS 日志组配置(控制台或 API)
日志组: demo-app-group(建议按应用分组)
日志流:
- demo-app-stdout(容器标准输出)
- demo-app-access(Nginx/Istio 访问日志)
- demo-app-audit(操作审计日志)
# 配置 CCE 对接 LTS
# CCE 控制台 → 日志采集策略 → 添加策略
# 策略名称: demo-app-log
# 采集类型: 容器标准输出
# 匹配规则: app=demo-app
# 目标日志流: demo-app-stdout
# 结构化解析: JSON 自动解析
3.5 日志查询实战
# LTS 日志搜索语法(类 Lucene)
# 1. 全文搜索
"订单支付失败"
# 2. 字段搜索
level:ERROR AND app:demo-app
# 3. 范围搜索
duration:[3000 TO *] AND level:ERROR
# 4. 排除
level:ERROR NOT logger:"com.demo.health"
# 5. 通配符
logger:com.demo.order.* AND level:ERROR
# 6. 组合查询(查看某笔订单的所有日志)
(orderId:ORD20260415001) AND (level:INFO OR level:ERROR OR level:WARN)
⚠️ 第四步:自定义告警规则
4.1 AOM 告警规则
# =====================
# 告警规则 1:Pod 频繁重启
# =====================
告警名称: 容器异常重启
指标: container_restart_count
统计周期: 5 分钟
聚合方式: sum by(pod_name)
条件: >= 3
严重级别: 紧急
通知方式: SMN → 短信 + 邮件
通知模板: "【华为云告警】{pod_name} 在 5 分钟内重启 {value} 次,请立即检查"
# =====================
# 告警规则 2:响应时间飙高
# =====================
告警名称: P99 响应时间异常
指标: apm_http_server_duration_p99
统计周期: 1 分钟
聚合方式: avg
条件: >= 3000
严重级别: 严重
通知方式: SMN → 企业微信 Webhook
通知模板: "【响应时间告警】P99={value}ms,超过阈值 3000ms,请排查慢调用"
# =====================
# 告警规则 3:错误率飙升
# =====================
告警名称: 接口错误率异常
指标: apm_http_server_error_rate
统计周期: 5 分钟
聚合方式: avg
条件: >= 5%
严重级别: 严重
通知方式: SMN → 短信
通知模板: "【错误率告警】当前错误率={value}%,超过 5%,请紧急排查"
# =====================
# 告警规则 4:JVM 内存告警
# =====================
告警名称: JVM 堆内存使用率过高
指标: jvm_heap_memory_used_percent
统计周期: 5 分钟
聚合方式: max by(pod_name)
条件: >= 90%
严重级别: 严重
通知方式: SMN → 邮件 + 微信
通知模板: "【JVM 告警】{pod_name} 堆内存使用率 {value}%,建议 dump 分析"
# =====================
# 告警规则 5:磁盘空间不足
# =====================
告警名称: 节点磁盘使用率过高
指标: disk_used_percent
统计周期: 5 分钟
聚合方式: max by(node_name)
条件: >= 85%
严重级别: 警告
通知方式: SMN → 邮件
4.2 SMN 通知配置
# 创建 SMN 主题
# 控制台 → 消息通知服务 SMN → 创建主题
# 主题名称: demo-app-alarm
# 显示名称: 生产环境告警
# 添加订阅
# 协议: SMS(短信)/ Email(邮件)/ Webhook(企业微信/钉钉)
# 终端:
# - SMS: +8613800138000(值班运维)
# - Email: ops@demo.com(运维组邮箱)
# - Webhook: https://qyapi.weixin.qq.com/...(企业微信机器人)
# 确认订阅(邮件/短信会收到确认链接,需手动确认)
🔥 踩坑经验 2: 避免"告警风暴"!刚上线时不要一次性开启所有告警规则,从最核心的 5 条规则开始,逐步增加。否则半夜被数十条重复告警轰炸,反而会忽视真正的故障。
4.3 智能降噪:告警静默期
# AOM → 告警管理 → 告警降噪
规则名称: 夜间低峰期降噪
生效时间: 00:00 - 06:00
降噪策略:
- 非严重级别告警自动合并
- 紧急告警仍单独通知
- WARN 级别告警仅记录不通知
规则名称: 发布窗口静默
生效时间: 发布时手动开启
降噪策略:
- 所有告警仅记录,不通知(发布期间预期会有波动)
- 发布完成后自动恢复
🚀 第五步:业务指标埋点
APM 自动采集的是系统级指标,业务指标需要手动埋点。
5.1 Micrometer 埋点
在 Spring Boot 中集成 Micrometer,将业务指标上报到 AOM:
<dependency>
<groupId>io.micrometer</groupId>
<artifactId>micrometer-registry-prometheus</artifactId>
</dependency>
@Component
public class OrderMetrics {
private final MeterRegistry meterRegistry;
// 订单总量
private final Counter orderTotal;
// 支付成功率
private final Counter orderSuccess;
private final Counter orderFailed;
// 订单处理耗时
private final Timer orderProcessTime;
// 实时订单数
private final Gauge activeOrders;
public OrderMetrics(MeterRegistry meterRegistry) {
this.meterRegistry = meterRegistry;
this.orderTotal = Counter.builder("demo.order.total")
.description("订单总量")
.register(meterRegistry);
this.orderSuccess = Counter.builder("demo.order.success")
.description("支付成功数")
.register(meterRegistry);
this.orderFailed = Counter.builder("demo.order.failed")
.description("支付失败数")
.register(meterRegistry);
this.orderProcessTime = Timer.builder("demo.order.process.time")
.description("订单处理耗时")
.publishPercentiles(0.5, 0.95, 0.99)
.register(meterRegistry);
this.activeOrders = Gauge.builder("demo.order.active", this,
OrderMetrics::getActiveOrderCount)
.description("活跃订单数")
.register(meterRegistry);
}
public void recordOrder(boolean success, long durationMs) {
orderTotal.increment();
if (success) {
orderSuccess.increment();
} else {
orderFailed.increment();
}
orderProcessTime.record(Duration.ofMillis(durationMs));
}
private int getActiveOrderCount() {
// 从数据库/缓存查询活跃订单数
return 42;
}
}
5.2 AOM 采集 Prometheus 指标
# CCE 配置 Prometheus 指标采集
# CCE 控制台 → 监控中心 → 指标采集规则
apiVersion: monitoring.coreos.com/v1
kind: ServiceMonitor
metadata:
name: demo-app-monitor
namespace: default
spec:
selector:
matchLabels:
app: demo-app
endpoints:
- port: http
path: /actuator/prometheus
interval: 15s
💡 提示: Spring Boot Actuator 的
/actuator/prometheus端点默认不开启,需配置:management: endpoints: web: exposure: include: health,prometheus metrics: export: prometheus: enabled: true
🔬 实战:故障排查全流程
业务场景:用户反馈"下单很慢"

实战命令汇总
# 1. AOM 查询当前指标
curl -s "https://aom.cn-north-4.myhuaweicloud.com/v1/${PROJECT_ID}/api/v1/query" \
-H "X-Auth-Token: ${TOKEN}" \
--data-urlencode 'query=apm_http_server_error_rate{app="demo-app"}' | jq .
# 2. 查看 APM 慢调用
# 控制台 → APM → 应用监控 → demo-app → 事务追踪
# 按响应时间降序排序,找到最慢的事务
# 3. 查看 APM 慢 SQL
# 控制台 → APM → 数据库 → 慢查询
# 可以看到具体 SQL 语句、执行计划、扫描行数
# 4. LTS 日志搜索慢查询
# 控制台 → LTS → 日志搜索
# 查询语句: duration:[3000 TO *] AND message:"Slow query"
# 5. 临时降级(如 MySQL 挂了)
kubectl scale deployment demo-app --replicas=5 -n default
# 或者启动降级逻辑
curl -X POST "https://api.demo.com/actuator/circuitbreaker/demo-db?state=open"
💰 成本核算
AOM/APM/LTS 计费
| 产品 | 免费额度 | 生产环境月估算 |
|---|---|---|
| AOM(指标) | 500 万指标/月 | 免费 ~ ¥300 |
| APM(链路) | 100 万 Span/天 | ¥200 ~ ¥800 |
| LTS(日志) | 500MB/月 | ¥100 ~ ¥500 |
| SMN(通知) | 100 条短信/月 | ¥20 ~ ¥100 |
| 合计 | — | ¥320 ~ ¥1,700/月 |
对于中小团队(10 个微服务),月成本约 ¥500。相比自建 Prometheus + Grafana + ELK 的运维成本(人工 ≈ ¥20,000/月),性价比极高。
📊 性能数据:监控系统本身的开销
| Agent 类型 | CPU 额外开销 | 内存开销 | 网络开销 | 启动时间影响 |
|---|---|---|---|---|
| APM Agent(10% 采样) | +2~3% | +64MB | +50KB/min | +3s |
| APM Agent(100% 采样) | +8~12% | +256MB | +5MB/min | +5s |
| Prometheus JMX Exporter | +1~2% | +32MB | +100KB/min | +1s |
| Logstash Encoder | +0.5% | +8MB | — | 无影响 |
实测: 10% 采样率下,APM Agent 对 2C4G 的 Java 应用影响完全可忽略(CPU +2.3%,RT +15ms)。
❓ 常见问题
Q1: APM Agent 启动失败怎么办?
错误日志: "Failed to connect to APM collector"
排查步骤:
- 检查 APM AK/SK 是否正确(注意区分 IAM 的 AK/SK 和 APM 的 AK/SK)
- 检查网络策略:CCE 集群能否访问
*.apm.myhuaweicloud.com - 配置 DNS:CCE 默认 CoreDNS,确保能解析公网域名
- 如果使用 VPC Endpoint,确认 Endpoint 已创建
Q2: APM 查不到调用链数据?
可能原因:
1. 采样率太低(确认 sampling_rate)
2. 应用没有实际流量(发几个请求测试)
3. APM Agent 版本不兼容 Java 版本
4. 防火墙拦截 APM 上报端口(443/8090)
Q3: LTS 日志显示不全?
排查:
1. 确认容器日志输出到 stdout,不是文件
2. 确认 LTS 日志采集策略匹配到 Pod 标签
3. 检查日志组配额(默认 10GB/月,超量丢弃)
4. 结构化日志需要开启 JSON 解析
Q4: 告警接收不到通知?
排查:
1. SMN 主题是否已确认订阅(邮件/短信需要确认)
2. 告警规则是否处于"启用"状态
3. 通知间隔是否设置过长(默认 30 分钟重复通知)
4. 是否在告警静默期内
Q5: JVM 指标为空?
排查:
1. APM Agent 配置 apm.jvm.enabled=true
2. Spring Boot 版本 ≥ 2.3(低版本需手动添加 Actuator)
3. 确认应用已重启生效
4. 查看 APM Agent 日志:kubectl logs {pod_name} -c demo-app | grep apm
🔥 踩坑实录
踩坑 1:APM Agent 版本与 Spring Boot 版本不兼容
现象: 添加 APM Agent 后应用启动失败,报 ClassNotFoundException。
根因: apm-javaagent-3.7.x 与 Spring Boot 3.3+ 的字节码增强冲突。
解决:
# 升级到 v3.8.0+(2025 年 12 月发布,兼容 Spring Boot 3.x)
wget https://apm2-cn-north-4.obs.cn-north-4.myhuaweicloud.com/apm-javaagent/apm-javaagent-3.8.0.tar.gz
# 如果仍需使用旧版本,添加排除配置
JAVA_TOOL_OPTIONS="... -Dapm.agent.exclude_class=org.springframework.*"
踩坑 2:日志 JSON 编码器导致行数爆炸
现象: 日志量从每天 200MB 飙升到 2GB,LTS 费用暴涨。
根因: Logstash Encoder 每条日志包含完整 stackTrace 字段,异常堆栈被重复记录。
解决:
<encoder class="net.logstash.logback.encoder.LogstashEncoder">
<!-- 堆栈截断,只保留前 5 行 -->
<throwableConverter class="net.logstash.logback.stacktrace.ShortenedThrowableConverter">
<maxLength>1000</maxLength>
<shortenedClassNameLength>40</shortenedClassNameLength>
<exclude>reactor\.core\.*</exclude>
</throwableConverter>
</encoder>
踩坑 3:告警规则太多,每周收到 500+ 告警
现象: 每次发布后告警不断,运维同学全部静默了通知。
根因: 不要一次性创建 20+ 告警规则,从核心到边缘逐步添加。
解决策略:

📝 总结与展望
本文总结
要点总结:
- ✅ AOM 监控大盘 — 20+ 预置大盘 + 自定义看板构建
- ✅ APM 全链路追踪 — Agent 接入、慢 SQL 定位、调用链分析
- ✅ LTS 日志管理 — 结构化日志、JSON 格式、全文搜索
- ✅ 告警规则配置 — 5 条核心规则、SMN 通知、降噪策略
- ✅ 业务指标埋点 — Micrometer + Prometheus 自定义指标
- ✅ 故障排查全流程 — 从用户反馈到根因定位
💡 互动话题: 你遇到过最离谱的监控事故是什么?欢迎在评论区分享你的"踩坑"经验!
- 点赞
- 收藏
- 关注作者
评论(0)