Skip to content
markdown
# Spring Batch 监控与指标详解 ⏱️

> 本文基于 Spring Batch 4.2+ 版本,将指导您使用 Micrometer 实现批处理作业的全方位监控

## 一、监控能力概述

Spring Batch 4.2+ 深度集成 [Micrometer](https://micrometer.io/) 提供开箱即用的监控指标。这些指标自动注册到 **Micrometer 全局注册表**,前缀为 `spring.batch`

::: tip 核心价值

- **实时洞察**:监控作业/步骤执行时长
- **性能分析**:定位读取/处理/写入瓶颈
- **运行状态**:跟踪活跃任务数量
- **故障诊断**:快速识别失败操作
  :::

```mermaid
sequenceDiagram
    participant App as 批处理应用
    participant SB as Spring Batch
    participant Micrometer
    participant Backend as 监控后端(Prometheus等)

    App->>SB: 执行批处理作业
    SB->>Micrometer: 自动发送指标数据
    Micrometer->>Backend: 存储和聚合指标
    Backend->>Grafana: 可视化展示
```

二、内置监控指标

无需额外配置,默认提供以下指标:

指标名称类型说明标签(Tags)
spring.batch.jobTIMER作业执行时长name, status
spring.batch.job.activeLONG_TASK_TIMER当前活跃作业数量name
spring.batch.stepTIMER步骤执行时长name, job.name, status
spring.batch.step.activeLONG_TASK_TIMER当前活跃步骤数量name
spring.batch.item.readTIMER数据读取时长job.name, step.name, status
spring.batch.item.processTIMER数据处理时长job.name, step.name, status
spring.batch.chunk.writeTIMER数据块写入时长job.name, step.name, status

IMPORTANT

status 标签仅有两个可能值:

  • SUCCESS:操作成功完成
  • FAILURE:操作执行失败

三、自定义指标实现

直接在自定义组件中使用 Micrometer API:

1. 计时任务示例 (Kotlin)

kotlin
import io.micrometer.core.instrument.Metrics
import io.micrometer.core.instrument.Timer
import org.springframework.batch.core.StepContribution
import org.springframework.batch.core.scope.context.ChunkContext
import org.springframework.batch.core.step.tasklet.Tasklet
import org.springframework.batch.repeat.RepeatStatus

class CustomTimedTasklet : Tasklet {

    override fun execute(contribution: StepContribution, chunkContext: ChunkContext): RepeatStatus? {
        val sample = Timer.start(Metrics.globalRegistry)
        var status = "success"

        try {

            // 业务逻辑实现
            TimeUnit.SECONDS.sleep(2) // 模拟耗时操作
        } catch (e: Exception) {
            status = "failure"
            // 异常处理逻辑
        } finally {
            sample.stop(Timer.builder("custom.tasklet.timer")
                .description("自定义任务执行时间")
                .tag("status", status)
                .register(Metrics.globalRegistry))
        }
        return RepeatStatus.FINISHED
    }
}

2. 注解配置方式

kotlin
@Configuration
@EnableBatchProcessing
class BatchConfig {

    @Bean
    fun customTasklet(): Tasklet = CustomTimedTasklet()

    @Bean
    fun job(jobBuilderFactory: JobBuilderFactory): Job {
        return jobBuilderFactory.get("monitoredJob")
            .start(step(null))
            .build()
    }

    @Bean
    fun step(stepBuilderFactory: StepBuilderFactory?): Step {
        return stepBuilderFactory!!.get("timedStep")
            .tasklet(customTasklet())
            .build()
    }
}

关键注意事项

  1. 线程安全:全局注册表 Metrics.globalRegistry 是线程安全的
  2. 标签规范:自定义指标建议遵循 domain.action 命名规范
  3. 避免过度监控:高频操作添加监控可能影响性能

四、指标禁用方案

通过 Micrometer 的过滤器禁用指标:

kotlin
// 禁用所有Spring Batch指标
Metrics.globalRegistry.config().meterFilter(
    MeterFilter.denyNameStartsWith("spring.batch")
)

// 选择性禁用特定指标
Metrics.globalRegistry.config().meterFilter(
    MeterFilter.deny { id ->
        id.name.startsWith("spring.batch.job.active")
    }
)
kotlin
// 禁用所有批处理相关指标
denyNameStartsWith("spring.batch")
kotlin
// 仅禁用作业活跃指标
deny { id -> id.name == "spring.batch.job.active" }

五、实战:集成 Prometheus

1. 添加依赖

kotlin
// build.gradle.kts
implementation("io.micrometer:micrometer-registry-prometheus:1.10.0")

2. 暴露指标端点 (Spring Boot)

kotlin
@Configuration
class MonitoringConfig {

    @Bean
    fun prometheusMeterRegistry(): PrometheusMeterRegistry {
        val registry = PrometheusMeterRegistry(PrometheusConfig.DEFAULT)
        Metrics.addRegistry(registry)
        return registry
    }
}

3. 配置 application.yml

yaml
management:
  endpoints:
    web:
      exposure:
        include: prometheus
  metrics:
    export:
      prometheus:
        enabled: true

六、最佳实践建议

  1. 标签使用规范 👇

  2. 监控关键指标

    • 作业失败率:count_spring_batch_job_seconds_count{status="failure"}
    • 平均处理时长:spring_batch_item_process_seconds_sum
    • 活跃任务数:spring_batch_job_active_seconds_active_count
  3. Grafana 看板配置示例

    sql
    -- 最近1小时作业成功率
    SELECT
      job_name,
      sum(status = 'SUCCESS') * 100.0 / count(*) as success_rate
    FROM batch_job_metrics
    WHERE time > now() - 1h
    GROUP BY job_name

TIP

生产环境建议结合日志跟踪(如 Sleuth)和指标监控,使用以下关联方案:

kotlin
// 在任务中注入Trace上下文
@StepScope
@Bean
fun traceAwareTasklet(tracer: Tracer) = Tasklet { contribution, _ ->
  val span = tracer.nextSpan().name("customStep").start()
  try {
    // 业务逻辑
  } finally {
    span.end()
  }
}

通过本文您已掌握: ✅ Spring Batch 内置监控指标的使用
✅ 自定义监控指标的开发技巧
✅ 生产环境监控方案集成
✅ 可视化看板配置方法

【附】Micrometer 官方文档Spring Batch Metrics 源码