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

如何将HikariCP默认Counter类型的connections.timeout指标改为Gauge暴露?

HikariCP连接超时指标改为Gauge类型的实现方案

首先明确核心前提:HikariCP原生hikaricp.connections.timeout为累计计数Counter,且连接超时是瞬时触发的离散事件,不存在持续的“超时中”状态,因此Gauge输出的实时动态值本质为指定时间窗口内的超时统计值,或单位时间的超时发生速率。之前自定义Gauge无法获取数据的核心原因是:没有将取值逻辑和HikariCP内部的超时事件触发点绑定,仅传入了无实际取值逻辑的Supplier。


方案1:自定义MetricsTracker(最灵活,完全可控)

HikariCP提供了MetricsTrackerFactory扩展点,可完全替换默认的指标采集逻辑,无需修改源码:

  • 第一步:实现自定义MetricsTracker,通过滑动窗口维护实时超时计数
import com.zaxxer.hikari.metrics.AbstractMetricsTracker;
import com.zaxxer.hikari.metrics.PoolStats;
import io.micrometer.core.instrument.Clock;
import io.micrometer.core.instrument.Gauge;
import io.micrometer.core.instrument.MeterRegistry;
import io.micrometer.core.instrument.distribution.SlidingWindowCounter;
import java.time.Duration;

public class RealTimeTimeoutMetricsTracker extends AbstractMetricsTracker {
    private final SlidingWindowCounter timeoutWindowCounter;

    public RealTimeTimeoutMetricsTracker(PoolStats poolStats, MeterRegistry registry) {
        super(poolStats);
        // 初始化滑动窗口:60个时间分片,每个分片1秒,统计最近60秒的超时总数
        this.timeoutWindowCounter = new SlidingWindowCounter(
                Clock.SYSTEM,
                60,
                Duration.ofSeconds(1)
        );

        // 注册自定义Gauge,直接返回窗口内的实时超时数
        Gauge.builder("hikaricp.connections.timeout.realtime", timeoutWindowCounter, SlidingWindowCounter::count)
                .description("Real-time connection timeout count in last 60 seconds")
                .tag("pool", poolStats.getPoolName())
                .register(registry);
    }

    // 每次连接超时事件触发时,给窗口计数+1
    @Override
    public void recordConnectionTimeout(long timeoutMs) {
        timeoutWindowCounter.increment();
    }
}
  • 第二步:实现自定义MetricsTrackerFactory,返回上述Tracker实例
import com.zaxxer.hikari.metrics.IMetricsTracker;
import com.zaxxer.hikari.metrics.MetricsTrackerFactory;
import com.zaxxer.hikari.metrics.PoolStats;
import io.micrometer.core.instrument.MeterRegistry;

public class CustomHikariMetricsFactory implements MetricsTrackerFactory {
    private final MeterRegistry meterRegistry;

    public CustomHikariMetricsFactory(MeterRegistry meterRegistry) {
        this.meterRegistry = meterRegistry;
    }

    @Override
    public IMetricsTracker create(String poolName, PoolStats poolStats) {
        return new RealTimeTimeoutMetricsTracker(poolStats, meterRegistry);
    }
}
  • 第三步:将自定义工厂注入HikariCP配置,替换默认指标实现
HikariConfig config = new HikariConfig();
// 省略其他数据源配置...
config.setMetricsTrackerFactory(new CustomHikariMetricsFactory(meterRegistry));

方案2:轻量转换(无需替换整个MetricsTracker)

如果不需要自定义时间窗口,仅需要输出非累计的实时超时速率,可直接基于原生Counter派生Gauge,无需替换默认Tracker:

import io.micrometer.core.instrument.Counter;
import io.micrometer.core.instrument.Gauge;

// 获取HikariCP原生注册的超时Counter
Counter nativeTimeoutCounter = meterRegistry.get("hikaricp.connections.timeout")
        .tag("pool", "你的连接池名称")
        .counter();

// 注册Gauge,输出每秒超时发生速率
Gauge.builder("hikaricp.connections.timeout.rate", nativeTimeoutCounter, counter -> {
    // 可根据需求调整速率计算逻辑,这里实现的是启动以来的平均每秒超时数
    long uptimeSec = System.currentTimeMillis() / 1000;
    return uptimeSec > 0 ? counter.count() / uptimeSec : 0;
}).register(meterRegistry);

注意:该方案依赖原生Counter的累计值计算,若监控系统自身支持Counter的rate/irate计算(比如Prometheus),优先在监控查询层做速率转换,性能开销更低。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.26 11:51:20