Skip to content

Spring Boot Actuator Prometheus 端点详解 :chart_with_upward_trend:

什么是 Prometheus 端点?

在现代微服务架构中,监控和可观测性是系统稳定运行的基石。想象一下,如果你的应用就像一辆汽车,那么各种指标数据就是仪表盘上的各种表盘——油量、转速、温度等。而 Prometheus 端点就是这个"仪表盘"的数据输出接口。

NOTE

Prometheus 是一个开源的系统监控和告警工具包,广泛用于云原生环境中的应用监控。Spring Boot Actuator 的 prometheus 端点专门为 Prometheus 服务器提供标准格式的指标数据。

核心价值与解决的问题 💡

传统监控的痛点

在没有标准化监控的时代,开发者面临着这些困扰:

kotlin
// 传统做法:在代码中手动记录关键指标
@RestController
class UserController {
    
    private val logger = LoggerFactory.getLogger(UserController::class.java)
    
    @GetMapping("/users")
    fun getUsers(): List<User> {
        val startTime = System.currentTimeMillis() 
        
        try {
            val users = userService.findAll()
            val endTime = System.currentTimeMillis() 
            
            // 手动记录响应时间 - 难以聚合分析
            logger.info("获取用户列表耗时: ${endTime - startTime}ms") 
            
            return users
        } catch (e: Exception) {
            logger.error("获取用户列表失败", e) 
            throw e
        }
    }
}
kotlin
// 现代做法:通过 Micrometer + Prometheus 自动收集指标
@RestController
class UserController(
    private val userService: UserService,
    private val meterRegistry: MeterRegistry
) {
    
    @GetMapping("/users")
    @Timed(value = "user.get.all", description = "获取所有用户的时间") 
    fun getUsers(): List<User> {
        // 自动记录请求次数、响应时间、成功率等指标
        return userService.findAll() 
    }
}

Prometheus 端点的核心优势

  1. 标准化格式:提供符合 Prometheus 规范的指标格式
  2. 自动收集:无需手动编写监控代码,框架自动收集关键指标
  3. 丰富维度:支持多维度标签,便于细粒度分析
  4. 实时性:提供实时的应用运行状态数据

技术原理深度解析 ⚙️

指标收集与暴露流程

指标数据格式解析

Prometheus 使用特定的文本格式来描述指标,让我们深入了解:

text
# HELP 指标名称 指标描述信息
# TYPE 指标名称 指标类型
指标名称{标签键1="标签值1",标签键2="标签值2"} 指标数值 时间戳(可选)
text
# HELP jvm_memory_used_bytes JVM已使用内存字节数
# TYPE jvm_memory_used_bytes gauge
jvm_memory_used_bytes{area="heap",id="G1 Eden Space"} 2097152.0
jvm_memory_used_bytes{area="heap",id="G1 Old Gen"} 9.0288128E7
jvm_memory_used_bytes{area="nonheap",id="Metaspace"} 8.4721552E7

TIP

指标类型说明

  • gauge:瞬时值,如内存使用量、CPU使用率
  • counter:只增不减的计数器,如请求总数
  • histogram:分布统计,如响应时间分布
  • summary:摘要统计,类似histogram但计算方式不同

实战应用场景 🚀

1. 基础配置与启用

首先,让我们配置一个支持 Prometheus 监控的 Spring Boot 应用:

kotlin
dependencies {
    implementation("org.springframework.boot:spring-boot-starter-web")
    implementation("org.springframework.boot:spring-boot-starter-actuator") 
    implementation("io.micrometer:micrometer-registry-prometheus") 
}
yaml
management:
  endpoints:
    web:
      exposure:
        include: prometheus,health,info
  endpoint:
    prometheus:
      enabled: true
  metrics:
    export:
      prometheus:
        enabled: true

2. 自定义业务指标

除了框架自动收集的指标,我们还可以添加业务相关的自定义指标:

kotlin
@Service
class OrderService(
    private val meterRegistry: MeterRegistry
) {
    
    // 计数器:统计订单创建次数
    private val orderCreatedCounter = Counter.builder("orders.created.total") 
        .description("订单创建总数")
        .tag("service", "order")
        .register(meterRegistry)
    
    // 计时器:统计订单处理时间
    private val orderProcessingTimer = Timer.builder("orders.processing.duration") 
        .description("订单处理耗时")
        .register(meterRegistry)
    
    // 仪表盘:当前待处理订单数
    private val pendingOrdersGauge = Gauge.builder("orders.pending.count") 
        .description("待处理订单数量")
        .register(meterRegistry) { getPendingOrderCount().toDouble() }
    
    fun createOrder(orderRequest: OrderRequest): Order {
        return orderProcessingTimer.recordCallable { 
            try {
                val order = processOrder(orderRequest)
                orderCreatedCounter.increment() 
                order
            } catch (e: Exception) {
                // 可以添加错误计数器
                meterRegistry.counter("orders.created.errors", 
                    "error.type", e.javaClass.simpleName).increment()
                throw e
            }
        }!!
    }
    
    private fun processOrder(request: OrderRequest): Order {
        // 模拟订单处理逻辑
        Thread.sleep(100) // 模拟处理时间
        return Order(id = generateId(), amount = request.amount)
    }
    
    private fun getPendingOrderCount(): Int {
        // 实际业务中从数据库查询
        return 42
    }
}

3. 端点访问与数据获取

让我们看看如何访问和使用 Prometheus 端点:

bash
# 获取应用的所有 Prometheus 格式指标
curl http://localhost:8080/actuator/prometheus
bash
# 只获取 JVM 内存相关指标
curl "http://localhost:8080/actuator/prometheus?includedNames=jvm_memory_used_bytes,jvm_memory_committed_bytes"
bash
# 获取 OpenMetrics 格式的指标数据
curl -H "Accept: application/openmetrics-text; version=1.0.0; charset=utf-8" \
     http://localhost:8080/actuator/prometheus

4. 监控大屏配置示例

配合 Grafana,我们可以创建直观的监控大屏:

Grafana 查询示例
promql
# CPU 使用率
rate(process_cpu_seconds_total[5m]) * 100

# JVM 堆内存使用率
(jvm_memory_used_bytes{area="heap"} / jvm_memory_max_bytes{area="heap"}) * 100

# HTTP 请求 QPS
rate(http_server_requests_seconds_count[1m])

# 订单创建速率
rate(orders_created_total[5m])

# 平均响应时间
rate(http_server_requests_seconds_sum[5m]) / rate(http_server_requests_seconds_count[5m])

最佳实践与注意事项 ⚠️

1. 性能优化建议

IMPORTANT

指标数量控制:过多的指标会影响应用性能和存储成本。建议:

  • 限制高基数标签(如用户ID、订单号等)
  • 定期清理不再使用的指标
  • 使用合理的指标命名规范
kotlin
// ❌ 错误示例:高基数标签
meterRegistry.counter("user.login", "user.id", userId) 

// ✅ 正确示例:低基数标签
meterRegistry.counter("user.login", "user.type", userType) 

2. 安全性考虑

yaml
# 生产环境建议配置
management:
  endpoints:
    web:
      base-path: /internal/actuator
      exposure:
        include: prometheus
  endpoint:
    prometheus:
      enabled: true
  server:
    port: 9090 # # 使用独立端口

WARNING

在生产环境中,Prometheus 端点可能暴露敏感的系统信息。建议:

  • 使用独立的管理端口
  • 配置网络访问控制
  • 启用 Spring Security 保护

3. 指标命名规范

kotlin
// 遵循 Prometheus 命名约定
class MetricsConfiguration {
    
    companion object {
        // 基础指标前缀
        const val APP_PREFIX = "myapp"
        
        // 业务指标命名
        const val ORDER_CREATED = "${APP_PREFIX}_orders_created_total"
        const val ORDER_PROCESSING_TIME = "${APP_PREFIX}_orders_processing_duration_seconds"
        const val USER_ACTIVE = "${APP_PREFIX}_users_active_count"
    }
}

故障排查指南 🔧

常见问题与解决方案

问题1:端点无法访问

现象:访问 /actuator/prometheus 返回 404

解决方案

yaml
management:
  endpoints:
    web:
      exposure:
        include: prometheus # 确保暴露 prometheus 端点

问题2:指标数据为空

现象:端点可访问但返回的指标很少

可能原因

  • Micrometer Prometheus 依赖缺失
  • 自定义指标注册失败
  • 应用负载不足,部分指标未产生

总结 🎉

Spring Boot Actuator 的 Prometheus 端点为我们提供了一个强大而标准化的应用监控解决方案。它不仅解决了传统监控方式的痛点,还为构建现代化的可观测性体系奠定了基础。

核心收益

  • 开箱即用:无需复杂配置即可获得丰富的系统指标
  • 标准化:符合 Prometheus 生态规范,易于集成
  • 可扩展:支持自定义业务指标,满足个性化需求
  • 高性能:基于拉取模式,对应用性能影响最小

通过合理使用 Prometheus 端点,我们可以构建一个全面、实时、可靠的应用监控体系,为系统的稳定运行保驾护航! 🚀