1. 为什么需要生产级监控体系
在微服务架构中,服务实例数量多、部署分散,传统的日志排查方式已经无法满足运维需求。我曾经历过一次线上事故:某个核心服务的内存泄漏导致响应缓慢,但由于缺乏实时监控,直到用户投诉才发现问题,此时已经造成了业务损失。
Spring Boot Actuator + Prometheus + Grafana 这套组合能提供:
- 实时指标采集(JVM、HTTP请求、缓存等)
- 多维度数据聚合
- 可视化监控看板
- 灵活的告警机制
这套方案的优势在于:
- 零侵入性:Actuator已集成在Spring Boot中,只需添加依赖和简单配置
- 生态完善:Prometheus的Pull模型特别适合动态变化的微服务环境
- 扩展性强:Grafana支持多种数据源和自定义仪表盘
生产环境建议至少监控以下核心指标:请求成功率(HTTP状态码)、平均响应时间(RT)、JVM内存使用率、线程池状态、数据库连接池使用情况。
需要模型API调用? 免费领10W Token,多模型网关一键接入 Claude、DeepSeek 等主流模型。
2. 环境准备与组件部署
2.1 Spring Boot Actuator配置
在pom.xml中添加依赖:
xml复制<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
<dependency>
<groupId>io.micrometer</groupId>
<artifactId>micrometer-registry-prometheus</artifactId>
</dependency>
application.yml关键配置:
yaml复制management:
endpoints:
web:
exposure:
include: health,info,prometheus
metrics:
export:
prometheus:
enabled: true
tags:
application: ${spring.application.name} # 添加应用标签
配置后访问 /actuator/prometheus 可以看到类似这样的指标数据:
code复制# HELP jvm_memory_used_bytes The amount of used memory
# TYPE jvm_memory_used_bytes gauge
jvm_memory_used_bytes{area="heap",id="PS Survivor Space",} 1.048576E7
2.2 Prometheus安装与配置
使用Docker部署Prometheus:
bash复制docker run -d --name=prometheus \
-p 9090:9090 \
-v /path/to/prometheus.yml:/etc/prometheus/prometheus.yml \
prom/prometheus
prometheus.yml配置示例:
yaml复制scrape_configs:
- job_name: 'spring-boot-app'
metrics_path: '/actuator/prometheus'
static_configs:
- targets: ['host.docker.internal:8080'] # 修改为实际应用地址
scrape_interval: 15s
honor_labels: true
2.3 Grafana安装与数据源配置
Docker部署Grafana:
bash复制docker run -d --name=grafana \
-p 3000:3000 \
grafana/grafana-oss
登录Grafana后:
- 添加数据源 -> 选择Prometheus
- URL填写
http://prometheus:9090(同Docker网络)或http://host.docker.internal:9090 - 保存并测试连接
3. 核心指标监控实现
3.1 JVM监控配置
在Grafana中导入ID为4701的JVM监控面板,可以看到:
- 内存各区域使用情况(Heap/Non-Heap)
- 线程状态(RUNNABLE/BLOCKED/WAITING等)
- GC次数与耗时
- 类加载数量
关键指标说明:
| 指标名称 | 告警阈值建议 | 排查方向 |
|---|---|---|
| jvm_memory_used_bytes | >80% of max | 内存泄漏或配置不足 |
| jvm_gc_pause_seconds_sum | 每分钟>10s | GC频繁或内存不足 |
| jvm_threads_live | >应用配置的max*0.8 | 线程泄漏或并发突增 |
3.2 HTTP请求监控
通过micrometer自动收集的指标:
code复制http_server_requests_seconds_count{method="GET",uri="/api/users",status="200",...}
http_server_requests_seconds_sum{...}
建议配置的告警规则:
- 错误率告警:5分钟内5xx错误占比>1%
promql复制sum(rate(http_server_requests_seconds_count{status=~"5.."}[5m])) by (instance,uri) / sum(rate(http_server_requests_seconds_count[5m])) by (instance,uri) > 0.01 - 慢请求告警:P99响应时间>1s
promql复制histogram_quantile(0.99, sum(rate(http_server_requests_seconds_bucket[5m])) by (le,uri) ) > 1
3.3 自定义业务指标
示例:统计订单创建成功率
java复制@RestController
public class OrderController {
private final Counter orderCreateCounter;
public OrderController(MeterRegistry registry) {
this.orderCreateCounter = Counter.builder("order.create")
.tag("type", "total")
.register(registry);
}
@PostMapping("/orders")
public ResponseEntity createOrder() {
orderCreateCounter.increment();
// 业务逻辑...
}
}
Grafana中可以用以下PromQL查询成功率:
code复制rate(order_create_total{job="spring-boot-app"}[5m])
4. 高级配置与优化
4.1 安全防护配置
- Actuator端点安全:
yaml复制management:
server:
port: 8081 # 与业务端口分离
endpoints:
web:
base-path: /internal # 修改默认路径
security:
enabled: true
- Prometheus配置认证:
yaml复制basic_auth:
username: admin
password: ${PROMETHEUS_PASSWORD}
- Grafana匿名访问禁用:
code复制[auth.anonymous]
enabled = false
4.2 长期存储方案
Prometheus默认本地存储不适合长期数据保留,建议:
- 远程写入InfluxDB:
yaml复制remote_write:
- url: "http://influxdb:8086/api/v1/prom/write"
basic_auth:
username: admin
password: ${INFLUXDB_PASSWORD}
- 或使用VictoriaMetrics集群版替代Prometheus
4.3 动态服务发现
对于Kubernetes环境,修改prometheus.yml:
yaml复制scrape_configs:
- job_name: 'kubernetes-services'
kubernetes_sd_configs:
- role: service
relabel_configs:
- source_labels: [__meta_kubernetes_service_annotation_prometheus_io_scrape]
action: keep
regex: true
5. 生产环境踩坑记录
5.1 指标基数爆炸问题
现象:Prometheus存储快速增长,查询变慢
根因:高基数标签(如user_id作为标签)
解决方案:
- 避免将可变值作为标签
- 使用
histogram或summary代替counter记录细粒度数据 - 配置Prometheus的
limit参数:
yaml复制metric_relabel_configs:
- source_labels: [__name__]
regex: 'high_cardinality_.*'
action: drop
5.2 Prometheus抓取超时
现象:up指标频繁波动
排查步骤:
- 检查网络连通性
- 调整scrape_timeout(建议设为scrape_interval的2/3)
- 优化Actuator端点性能:
java复制@Configuration
public class MetricsConfig {
@Bean
public MeterRegistryCustomizer<MeterRegistry> metricsCommonTags() {
return registry -> registry.config().commonTags("region", "east");
}
}
5.3 Grafana告警配置
邮件告警配置示例:
- 修改grafana.ini:
code复制[smtp]
enabled = true
host = smtp.example.com:465
user = alert@example.com
password = xxx
from_address = alert@example.com
- 创建告警规则:
- 设置条件:
avg_over_time(up{job="spring-boot-app"}[5m]) < 1 - 配置告警消息模板:
code复制{{ define "alert.message" }}
[{{ .Status | toUpper }}] {{ .Labels.alertname }}
Instance: {{ .Labels.instance }}
Value: {{ .Value }}
{{ end }}
这套监控体系在我们生产环境运行两年多,成功预警了3次重大故障。建议每周review监控指标,根据业务变化调整阈值。对于关键业务指标,可以结合Spring AOP实现更细粒度的监控埋点。
