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

如何通过Micrometer将Hazelcast Map统计指标发送至Datadog

Spring Boot Cache + Hazelcast:缓存命中/未命中指标发送到Datadog

问题背景

我使用Spring Boot Cache实现Hazelcast缓存,希望将缓存命中、未命中指标发送至Datadog。已开启Hazelcast的统计功能与JMX,但指标未正常上报到Datadog。当前缓存可正常工作,且其他服务指标能正常发送至Datadog。

我尝试过自定义EntryListener,但发现该监听器仅支持监听添加、更新、删除、驱逐、过期及清空事件,无法直接统计命中/未命中——添加事件或许可对应未命中,但更新事件无法区分是命中后的更新还是其他场景。不想采用定期同步Map指标的方案,寻求更优解。

当前配置文件

hazelcast.yaml

hazelcast:
  network:
    join:
      multicast:
        enabled: false
      tcp-ip:
        enabled: false
#        change these 2 lines and set kubernetes enabled to false for local debug
#        enabled: true
#        members: 127.0.0.1
      kubernetes:
        enabled: true
        namespace: my-namespace
        service-name: my-service
  metrics:
    enabled: true
    jmx:
      enabled: true
  map:
    default:
      statistics-enabled: true
      time-to-live-seconds: 86400
      eviction:
        max-size-policy: PER_NODE
        eviction-policy: LFU
        size: 200000

application.yaml

management:
  endpoint:
    health:
      probes:
        enabled: true
  metrics:
    export:
      statsd:
        enabled: true
        flavor: datadog
        port: 8125
        host: ${HOST_IP}

解决方案

1. 修复Hazelcast与Micrometer的集成

Hazelcast本身会统计hazelcast.map.gets.hits和hazelcast.map.gets.misses指标,但需要确保这些指标被Spring Boot的Micrometer捕获:

  • 确保引入hazelcast-spring依赖(版本需与Spring Boot兼容,比如Spring Boot 3.x对应Hazelcast 5.x),该依赖会自动将Hazelcast的Map统计绑定到Micrometer的MeterRegistry。
  • 确认hazelcast.map.default.statistics-enabled: true已生效,该配置会开启默认Map的统计功能,所有基于此Map的缓存都会生成命中/未命中数据。

如果之前未生效,可能是依赖缺失或版本不匹配,检查项目的依赖管理配置。

2. 自定义Spring Cache拦截器(推荐方案)

如果原生集成仍有问题,或者需要更细粒度的指标控制,直接在Spring Cache抽象层实现拦截器,统计命中/未命中:

步骤1:实现带指标统计的CacheInterceptor

import io.micrometer.core.instrument.Counter;
import io.micrometer.core.instrument.MeterRegistry;
import org.springframework.cache.interceptor.CacheInterceptor;
import org.springframework.cache.interceptor.CacheOperationInvocationContext;
import org.springframework.cache.interceptor.CacheOperationInvoker;
import org.springframework.stereotype.Component;

@Component
public class MetricsCacheInterceptor extends CacheInterceptor {

    private final Counter cacheHits;
    private final Counter cacheMisses;

    public MetricsCacheInterceptor(MeterRegistry meterRegistry) {
        this.cacheHits = Counter.builder("cache.gets.hits")
                .tag("cache.provider", "hazelcast")
                .register(meterRegistry);
        this.cacheMisses = Counter.builder("cache.gets.misses")
                .tag("cache.provider", "hazelcast")
                .register(meterRegistry);
    }

    @Override
    protected Object invoke(final CacheOperationInvoker invoker, CacheOperationInvocationContext<?> context,
                           Cache.ValueWrapper result) {
        // 缓存命中:查询到缓存结果
        if (result != null) {
            cacheHits.increment();
        } else {
            // 缓存未命中:执行目标方法后会写入缓存
            cacheMisses.increment();
        }
        return super.invoke(invoker, context, result);
    }
}

步骤2:替换默认拦截器

创建配置类,将自定义拦截器设置为Spring Cache的默认拦截器:

import org.springframework.cache.annotation.EnableCaching;
import org.springframework.cache.interceptor.CacheInterceptor;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Primary;

@Configuration
@EnableCaching
public class CacheConfig {

    @Bean
    @Primary
    public CacheInterceptor cacheInterceptor(MeterRegistry meterRegistry) {
        return new MetricsCacheInterceptor(meterRegistry);
    }
}

这种方案直接基于Spring Cache的抽象层,无需依赖Hazelcast内部事件,指标会自动通过Micrometer发送至Datadog,还能灵活添加自定义标签(比如缓存名称、业务场景)。

3. 验证指标上报

  • 通过Spring Boot Actuator的/actuator/metrics端点,查询cache.gets.hits和cache.gets.misses是否存在数据。
  • 直接在Datadog平台搜索对应指标名称,确认数据是否正常上报。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.16 03:32:12