【问题标题】:Spring Batch and boot MicrometerSpring Batch 和 boot 千分尺
【发布时间】:2021-02-28 07:51:55
【问题描述】:

我有一个 Spring 批处理作业,它从 DB 中读取记录,对其进行处理,然后写入另一个数据库。我想测量 Spring 批处理器和 Writer 所花费的总时间/平均时间。根据文档 - https://docs.spring.io/spring-batch/docs/current/reference/html/monitoring-and-metrics.html 可以使用 spring.batch 前缀轻松获得这些指标。如何将处理器和写入器所花费的时间记录到控制台。当我在作业侦听器结束时从指标注册表打印指标结果时,我看到作业和步骤状态为已完成,但计时器统计指标显示为 0。是否需要执行任何操作才能启用计时器?我不打算将指标推送到 prometheus 或 atlas 或任何其他注册表。所以在 pom.xml 中只添加了 micrometer 核心依赖。请告知如何记录不同组件的耗时指标。任何例子都会很有帮助。

【问题讨论】:

    标签: logging spring-batch micrometer


    【解决方案1】:

    我看到作业和步骤状态为已完成,但计时器统计指标显示为 0。

    原因是默认情况下,以微米为单位的全局注册表是一个空的组合。您需要添加至少一个注册表来保留指标。见Why does MicroMeter Timer returns zero?

    我不打算将指标推送到 prometheus 或 atlas 或任何其他注册表。

    如果您想使用指标而不将它们推送到指标后端,您可以使用侦听器并直接从全局注册表获取访问权限。以下是您要求的项目处理时间的快速示例:

    import java.util.Arrays;
    import java.util.List;
    
    import io.micrometer.core.instrument.Measurement;
    import io.micrometer.core.instrument.Meter;
    import io.micrometer.core.instrument.Metrics;
    import io.micrometer.core.instrument.simple.SimpleMeterRegistry;
    
    import org.springframework.batch.core.ItemProcessListener;
    import org.springframework.batch.core.Job;
    import org.springframework.batch.core.JobParameters;
    import org.springframework.batch.core.configuration.annotation.EnableBatchProcessing;
    import org.springframework.batch.core.configuration.annotation.JobBuilderFactory;
    import org.springframework.batch.core.configuration.annotation.StepBuilderFactory;
    import org.springframework.batch.core.launch.JobLauncher;
    import org.springframework.batch.item.ItemProcessor;
    import org.springframework.batch.item.ItemReader;
    import org.springframework.batch.item.ItemWriter;
    import org.springframework.batch.item.support.ListItemReader;
    import org.springframework.context.ApplicationContext;
    import org.springframework.context.annotation.AnnotationConfigApplicationContext;
    import org.springframework.context.annotation.Bean;
    import org.springframework.context.annotation.Configuration;
    
    @Configuration
    @EnableBatchProcessing
    public class MyJob {
    
        @Bean
        public ItemReader<Integer> itemReader() {
            return new ListItemReader<>(Arrays.asList(0, 1, 2, 3, 4, 5, 6, 7, 8, 9));
        }
    
        @Bean
        public ItemProcessor<Integer, Integer> itemProcessor() {
            return item -> {
                System.out.println("processing item " + item);
                Thread.sleep(2000);
                return item + 1;
            };
        }
    
        @Bean
        public ItemWriter<Integer> itemWriter() {
            return items -> {
                for (Integer item : items) {
                    System.out.println("writing item = " + item);
                }
            };
        }
    
        @Bean
        public Job job(JobBuilderFactory jobs, StepBuilderFactory steps) {
            return jobs.get("job")
                    .start(steps.get("step")
                            .<Integer, Integer>chunk(5)
                            .reader(itemReader())
                            .processor(itemProcessor())
                            .writer(itemWriter())
                            .listener(new MonitoringItemProcessListener())
                            .build())
                    .build();
        }
        
        static class MonitoringItemProcessListener implements ItemProcessListener<Integer, Integer> {
    
            @Override
            public void beforeProcess(Integer item) {
                
            }
    
            @Override
            public void afterProcess(Integer item, Integer result) {
                List<Meter> meters = Metrics.globalRegistry.getMeters();
                for (Meter meter : meters) {
                    if (meter.getId().getName().equals("spring.batch.item.process")) {
                        System.out.println("meter description = " + meter.getId().getDescription());
                        Iterable<Measurement> measurements = meter.measure();
                        for (Measurement measurement : measurements) {
                            System.out.println("measurement: statistic = " + measurement.getStatistic() + " | value = " + measurement.getValue());
                        }
                    }
                }
            }
    
            @Override
            public void onProcessError(Integer item, Exception e) {
    
            }
        }
    
        public static void main(String[] args) throws Exception {
            Metrics.addRegistry(new SimpleMeterRegistry());
            ApplicationContext context = new AnnotationConfigApplicationContext(MyJob.class);
            JobLauncher jobLauncher = context.getBean(JobLauncher.class);
            Job job = context.getBean(Job.class);
            jobLauncher.run(job, new JobParameters());
        }
    
    }
    

    此示例打印如下内容:

    processing item 1
    meter description = Item processing duration
    measurement: statistic = COUNT | value = 1.0
    measurement: statistic = TOTAL_TIME | value = 2.00080715
    measurement: statistic = MAX | value = 2.00080715
    processing item 2
    meter description = Item processing duration
    measurement: statistic = COUNT | value = 2.0
    measurement: statistic = TOTAL_TIME | value = 4.003516877
    measurement: statistic = MAX | value = 2.002709727
    processing item 3
    meter description = Item processing duration
    measurement: statistic = COUNT | value = 3.0
    measurement: statistic = TOTAL_TIME | value = 6.005287923
    measurement: statistic = MAX | value = 2.002709727
    

    【讨论】:

    • 非常感谢...这有帮助..我会尝试样品并让您知道..
    • 谢谢..我已经接受了答案...所以声誉分数很低。因此不允许我投票。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-12-22
    • 2020-02-17
    • 2019-04-10
    • 1970-01-01
    • 2020-03-15
    • 1970-01-01
    相关资源
    最近更新 更多