如果 Guava 缓存绑定到 MeterRegistry,EhCache 指标不会出现在 Prometheus 中

问题描述 投票:0回答:1

隐式创建的EhCache缓存

我有一个 Spring 组件,它使用具有以下配置的文件

ehcache.xml
声明一些缓存:

<?xml version="1.0" encoding="UTF-8"?>
<eh:config
        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
        xmlns:eh="http://www.ehcache.org/v3"
        xsi:schemaLocation="http://www.ehcache.org/v3 http://www.ehcache.org/schema/ehcache-core-3.3.xsd">

    <eh:cache alias="Cache1">
        <eh:expiry>
            <eh:ttl unit="minutes">1</eh:ttl>
        </eh:expiry>
        <eh:resources>
            <eh:heap>10000</eh:heap>
        </eh:resources>
    </eh:cache>

<!-- [...] -->

</eh:config>

然后使用类似于以下内容:

import org.springframework.cache.annotation.Cacheable;

public class ThingDoer {
    @Cacheable("Cache1")
    public Integer doSomethingCached(int value) {
        return value + 3;
    }

    // ...
}

这样,我可以看到 Prometheus 中出现不同的缓存指标:

bash> 2>&1 curl -v --silent 'http://localhost:9000/actuator/prometheus' | grep cache_gets | sort

cache_gets_total{cache="Cache1",cache_manager="cacheManager",hostname="localhost",name="Cache1",result="hit",} 0.0
cache_gets_total{cache="Cache1",cache_manager="cacheManager",hostname="localhost",name="Cache1",result="miss",} 0.0
cache_gets_total{cache="Cache2",cache_manager="cacheManager",hostname="localhost",name="Cache2",result="hit",} 0.0
cache_gets_total{cache="Cache2",cache_manager="cacheManager",hostname="localhost",name="Cache2",result="miss",} 0.0
cache_gets_total{cache="Cache3",cache_manager="cacheManager",hostname="localhost",name="Cache3",result="hit",} 0.0
cache_gets_total{cache="Cache3",cache_manager="cacheManager",hostname="localhost",name="Cache3",result="miss",} 0.0
[...]

我在文件中定义的所有缓存

ehcache.xml
都会自动公开它们的指标。

添加自制缓存

现在,我创建了一个自制的缓存,它在查询时执行复杂的操作,并为此使用了

com.google.common.cache.LoadingCache
接口,因为它的目的是替换此类缓存的另一个实例,并对其余代码进行尽可能少的更改。因此,我创建了一个自定义缓存,具有以下签名:

import com.google.common.cache.AbstractLoadingCache;

public class CustomCache extends AbstractLoadingCache<String, Object> {
    public CustomCache(Function<String, Object> valueLoader) {
        // ...
    }

    // ...
}

它正确声明了一个

stats()
方法,该方法返回包含缓存统计信息的
com.google.common.cache.CacheStats
。其构造函数的参数
valueLoader
用于在缓存中缺少新值时加载新值。

现在,这是如何使用此缓存的草图:

import java.util.Optional;
import java.util.concurrent.ExecutionException;
import java.util.function.Function;

public class CustomThingDoer {
    private final CustomCache customCache;

    public CustomThingDoer() {
        this.customCache = new CustomCache(this::loadNewObject);
    }

    public Optional<Object> doSomethingCached(String value) {
        try {
            return Optional.of(customCache.get(value));
        } catch (ExecutionException e) {
            System.out.println("Something wrong happened");
            return Optional.empty();
        }
    }

    private Object loadNewObject(String value) {
        // Do something non-static
    }
}

由于缓存旨在直接调用其方法的地方使用(即没有

@Cacheable
注释来使用此缓存,而是使用对
get
的调用),并且由于加载缺失值的方法取决于在定义它的类的实例上(即,所讨论的方法是提取数据库,其代码取决于
CustomThingDoer
实例中定义的内容),我希望将其手动注册到
MeterRegistry
中。

为此,我将

MeterRegistry
的 bean 传递给构造函数中的
CustomThingDoer
,并执行以下操作:

GuavaCacheMetrics.monitor(meterRegistry, this.customCache, "MyCustomCache");

消失的缓存指标

但是现在这已经完成了,这就是我在 Prometheus 中获得的缓存指标:

bash> 2>&1 curl -v --silent 'http://localhost:9000/actuator/prometheus' | grep cache_gets | sort

cache_gets_total{cache="MyCustomCache",hostname="localhost",result="hit",} 0.0
cache_gets_total{cache="MyCustomCache",hostname="localhost",result="miss",} 0.0

现在,仅显示我的自定义缓存的指标。此外,字段

cache_manager
不存在。

我的怀疑是,由于我手动注册缓存,一些谓词被 automagic 破坏了,并且它永远不会将自动生成的 EhCache 缓存添加到

MeterRegistry

我想要同时拥有自定义缓存的指标以及隐式创建的 EhCache 缓存的指标。如果可能的话,我希望不必更改所使用的接口(即`com.google.common.cache.LoadingCache),以便对代码(并且老实说,对单元测试)进行最少的更改。有人知道问题可能是什么,或者我可能有什么解决方案吗?

prometheus guava ehcache spring-boot-actuator spring-micrometer
1个回答
0
投票

这似乎与 Micrometer 中的一个长期错误有关:https://github.com/micrometer-metrics/micrometer/issues/877

它在几年前就被修复了,但它仍然有副作用,其中每个指标名称必须具有相同的标签键集,否则有些不被考虑在内。 https://github.com/micrometer-metrics/micrometer/issues/877#issuecomment-944894069

© www.soinside.com 2019 - 2024. All rights reserved.