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

SpringBoot应用重启后Actuator自定义Prometheus指标重置为0如何解决

解决方案

方案1:PromQL层面处理(优先推荐,改造成本最低)

这是工业界最常用的解决方案,不需要修改应用代码或架构,利用Prometheus内置特性即可处理Counter重置问题

  • 你统计的请求计数属于Counter类型指标,PromQL的rate()、irate()、increase()函数本身已经内置了对Counter重置的处理逻辑:当检测到指标值比前一个样本小的时候,会自动判定Counter发生了重置,计算增量时会自动补上重置前的累计值。
  • 示例:如果你之前直接用your_request_counter_total原始值做图表展示导致骤降,改成用increase(your_request_counter_total[1m])计算1分钟内的请求增量,或者rate(your_request_counter_total[5m])计算平均QPS,就不会出现骤降到0的情况。
  • 注意:不要直接把Counter类型的原始值拿来做折线图展示,这类指标的核心用法是统计一段时间的增量、速率,原生函数已经完美适配了应用重启重置的场景。

方案2:应用侧指标持久化(适合需要保留全局累计值的特殊场景)

如果你的业务确实需要展示请求计数的全局累计值,无法用增量/速率替代展示,可以把指标从内存存储改成持久化存储:

  • 选择适配业务的持久化介质:单机部署可以用本地RocksDB、嵌入式数据库,分布式部署可以用Redis等共享存储。
  • 自定义MeterRegistry实现:继承Micrometer的SimpleMeterRegistry,重写Counter的存取逻辑,应用启动时从持久化介质读取之前的累计值作为初始值,每次Counter更新时同步写入持久化存储。
  • 核心代码示例:
// 基于Redis实现的持久化Counter
public class PersistentCounter extends AbstractCounter {
    private final String counterKey;
    private final RedisTemplate<String, Long> redisTemplate;

    public PersistentCounter(Id id, String counterKey, RedisTemplate<String, Long> redisTemplate) {
        super(id);
        this.counterKey = counterKey;
        this.redisTemplate = redisTemplate;
    }

    @Override
    public void increment(double amount) {
        redisTemplate.opsForValue().increment(counterKey, (long) amount);
    }

    @Override
    public double count() {
        Long value = redisTemplate.opsForValue().get(counterKey);
        return value != null ? value.doubleValue() : 0.0;
    }
}
  • 注意:多实例部署场景下要给每个实例的指标key添加唯一标识(比如实例IP、Pod名),避免不同实例的计数互相覆盖。

方案3:部署架构层面规避(云原生场景适用)

如果是Kubernetes部署的应用,可以配合发布策略降低重置影响:

  • 采用滚动发布策略,新旧实例共存一段时间,Prometheus可以同时抓取新旧实例的指标,避免所有实例同时重置导致指标整体骤降。
  • 配合Prometheus服务发现自动剔除下线实例,不需要额外修改指标逻辑。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.26 10:45:05