You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

为何DistributionSummary配置0.0抛异常但record(0.0)可正常执行?

问题

在使用Micrometer的DistributionSummary时,设置minimumExpectedValue或服务水平目标(SLO)为0.0会触发异常,但调用distributionSummary.record(0.0)上报0.0值却能正常执行。这种行为不一致的原因是什么?

我们主要用该DistributionSummary统计无小数的整数值,用0.001作为minimumExpectedValue和SLO的值虽然可行,但不符合常规。

示例代码

final PrometheusMeterRegistry registry =
        new PrometheusMeterRegistry(PrometheusConfig.DEFAULT).throwExceptionOnRegistrationFailure();

final DistributionSummary distributionSummary = DistributionSummary.builder("my_metric")
        .minimumExpectedValue(0.0)
        .maximumExpectedValue(100.0)
        .publishPercentileHistogram()
        .serviceLevelObjectives(0.0, 1, 2, 5, 10, 20, 50, 100)
        .baseUnit("listeners")
        .register(registry);

distributionSummary.record(0.0);

System.out.println(registry.scrape());

触发的异常

设置minimumExpectedValue(0.0)时的异常

io.micrometer.core.instrument.config.InvalidConfigurationException: Invalid distribution configuration: minimumExpectedValue (0.0) must be greater than 0.
    at io.micrometer.core.instrument.distribution.DistributionStatisticConfig$Builder.rejectConfig(DistributionStatisticConfig.java:503)
    at io.micrometer.core.instrument.distribution.DistributionStatisticConfig$Builder.validate(DistributionStatisticConfig.java:478)
    at io.micrometer.core.instrument.distribution.DistributionStatisticConfig$Builder.build(DistributionStatisticConfig.java:460)
    at io.micrometer.core.instrument.DistributionSummary$Builder.register(DistributionSummary.java:418)
    at io.micrometer.core.instrument.DistributionSummary$Builder.register(DistributionSummary.java:413)
    ....

设置serviceLevelObjectives(0, ...)时的异常

io.micrometer.core.instrument.config.InvalidConfigurationException: Invalid distribution configuration: serviceLevelObjectiveBoundaries must contain only the values greater than 0. Found 0.0
    at io.micrometer.core.instrument.distribution.DistributionStatisticConfig$Builder.rejectConfig(DistributionStatisticConfig.java:503)
    at io.micrometer.core.instrument.distribution.DistributionStatisticConfig$Builder.validate(DistributionStatisticConfig.java:495)
    at io.micrometer.core.instrument.distribution.DistributionStatisticConfig$Builder.build(DistributionStatisticConfig.java:460)
    at io.micrometer.core.instrument.DistributionSummary$Builder.register(DistributionSummary.java:418)
    at io.micrometer.core.instrument.DistributionSummary$Builder.register(DistributionSummary.java:413)
    ...

使用的依赖

  • micrometer-core:1.12.3
  • micrometer-registry-prometheus:1.11.3

原因分析与解决方案

行为不一致的核心原因

  1. 配置参数的设计逻辑:

    • minimumExpectedValue用于定义统计分布的下限,Micrometer的百分位数直方图等高级统计功能依赖这个值划分区间桶。如果设为0.0,会生成无效的零宽度桶,破坏统计逻辑,因此配置阶段直接校验拦截。
    • SLO边界值是用来计算"低于该值的样本占比",0.0作为边界没有实际统计意义——所有非负样本都满足≥0,无法区分服务水平差异,所以配置时也会被拦截。
  2. record方法的兼容性设计:
    record(0.0)允许上报0值,是因为DistributionSummary本身支持统计所有非负数值(包括0)。上报0只会被计入总和、计数等基础统计项,不会触发依赖minimumExpectedValue或SLO边界的复杂统计逻辑,因此不会触发错误。

适配整数统计场景的方案

针对你用它统计无小数整数值的场景,推荐两种合规方案:

  1. 拆分统计逻辑:
    把minimumExpectedValue设为1.0,同时单独用一个Counter来统计0值的出现次数。这样既符合Micrometer的配置规范,又能完整覆盖所有数据场景。
  2. 更换适配的指标类型:
    如果你的统计场景更偏向整数计数,可以考虑切换到LongTaskTimer,或者用"Counter + Gauge"的组合来实现,避免DistributionSummary的小数统计特性带来的配置冲突。

内容的提问来源于stack exchange,提问作者palacsint

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.28 22:45:54