[spring-projects/spring-boot]自动为动态创建的缓存创建指标

2024-04-23 265 views
8

目前,它为所有已知的缓存名称CacheMetricsRegistrarConfiguration绑定了缓存相关指标的计量表。@PostContstruct

查看该spring-boot-sample-cache项目和各种缓存实现,其中大多数目前不提供缓存名称,因此没有提供这些指标。

回答

4

这个问题的描述是在文档中公布的

他们中的大多数目前不提供缓存名称

缓存名称是缓存的强制参数,因此我不确定我是否理解您所报告的内容。

1

好的,在文档中错过了这一点。但我想知道情况是否可以改善?

并且还spring-boot-sample-cache应该使用该CacheMetricsRegistrar选项(目前还没有)。我会自愿为此做一个公关。

5

我目前不知道如何改进事情。在调查了我们如何改进之后,这一点被记录下来。如果你找到了方法,我非常乐意审查 PR。

至于缓存示例,我还是不明白你的意思,抱歉。并非所有缓存都受微米支持,因此这可能是您看不到指标的原因。如果您有更多问题,请在 StackOverflow 上提问或在 Gitter 上与我们聊天。

9

@snicoll 我遇到了同样的问题,并对如何处理它有一些想法。我愿意提出 PR,但我正在寻求有关哪种方法的指导:

当前缓存指标的自动配置将仅绑定启动时已知的缓存。这意味着,在开发人员使用 的情况下@Cacheable,任何“即时”创建的缓存都不会将其指标绑定到MeterRegistry.

这是令人惊讶的行为,并且期望所有缓存(无论是动态的还是其他方式)都通过微米来暴露其指标似乎是合理的。

这实际上是一个棘手的问题,因为每个CacheManager实现都必须能够感知电表。具体来说,缓存在CacheManager.getCache(String name)调用时应该绑定到注册表。执行此操作的最佳位置是AbstractCacheManager(在核心 Spring 框架中),但是CacheMetricsRegistrar(用于将缓存绑定到MeterRegistry)位于 Spring Boot Actuator 项目中。

我可以想到两种方法来使其正确工作,这样当执行器库添加到类路径时,所有缓存都将其指标绑定到MeterRegistry

  • CacheCreatedEvent从内部发布AbstractCacheManager.考虑到注册器的内部结构,该事件必须具有缓存名称和创建它的缓存管理器。这将允许在执行器库中定义监听器,将每个缓存连接到仪表注册表。这种方法还意味着不再需要@PostConstructCacheMetricsRegistrarConfiguration启动时绑定已知缓存的方法,因为所有缓存都会触发对getCache.这种方法意味着要更改核心 Spring 库的 Cache,然后更改 Spring Boot 的执行器。

  • 创建一个绑定到 的 Aspect CacheManager.getCache(String name)。这方面将使用注册器将缓存绑定到MeterRegistry.这种方法还使得不需要单独@PostConstruct注册已知缓存,并且只需要在执行器库中进行更改。

7

我个人更喜欢尽可能避免某些方面,但这个活动的想法对我来说听起来相当不错。

3

我喜欢这个活动的想法。请在框架问题跟踪器中创建一个问题,我会尝试一下。

0

我已经重新打开了它,这样它就不会从裂缝中消失。在框架问题得出结论之前,它会被阻止。

7

我们需要更多的时间来调查哪种合同在该级别上是合理的。我已经评论过框架问题

6

阅读@snicoll 的反馈后,没有具体的机制来强制每个缓存管理实现在启动时或动态创建缓存时发出事件。经过更多思考后,也许我们可以从 spring cloud sleuth 那里借鉴一下:如果执行器库创建一个 BeanPostProcessor 将 CacheManager 包装在一个 中,会怎么样MetricsAwareCacheManager?该管理器可以跟踪哪些名称已经/尚未绑定到仪表注册表。

它会类似于这样:

https://github.com/spring-cloud/spring-cloud-sleuth/blob/master/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/instrument/async/AsyncCustomAutoConfiguration。爪哇

4

我原型化了使用 aBeanPostProcessor创建一个包装器,虽然CacheManager这有效,但相当混乱。代理必须跟踪哪些名称已经/尚未绑定到仪表注册表,并且必须在每次CacheManager.getCache()调用时检查该列表。此外,使用包装器将排除按类型自动装配 CacheManager 的能力,这是不理想的。看起来最好的选择仍然是从每个 CacheManager 实现生成一个事件。

2

嗨,抱歉,如果我在这里遗漏了一些东西。我一直在玩 Spring Boot 缓存示例。https://github.com/spring-projects/spring-boot/tree/master/spring-boot-samples/spring-boot-sample-cache

我了解动态创建的缓存的问题。当我运行示例时,如果我不在文件中添加spring.cache.cache-names=countries,我不会在countries缓存中获得任何咖啡因统计信息。但是当我使用 hazelcast 配置文件时,我希望获得这些统计信息,因为提供了 hazelcast.xml 文件。 Infinispan 不起作用,但这是可以理解的,因为它不受支持。

7

@karesti 请在 StackOverflow 上提问或在 Gitter 上加入我们。

5

从 #19412 开始,值得一提的是,通过创建的缓存@CacheConfig也被视为“动态”。

尽管文档说指标注册表仅绑定启动时可用的缓存。直觉上,我认为这@CacheConfig也被认为是在启动时可用。

只有启动时可用的缓存才会绑定到注册表。对于在启动阶段后即时或以编程方式创建的缓存,需要显式注册。提供了 CacheMetricsRegistrar bean 来简化该过程。

4

@jorgheymans,@CacheConfig这里无关紧要。只是您使用的缓存提供程序被配置为在缓存不存在时动态创建缓存。在代码中通过引用缓存的名称@CacheConfig绝不是注册。

1

我认为在文档的现有部分中值得注意这一点。为此,我将重新打开#19412。

7

选项 1:发送事件,或从公共基类扩展意味着所有现有的缓存管理器都需要更改。选项 2:AOP 可以避免对现有类的更改,但它是隐式的并且容易出错。这是一种平衡。我们首先选择要走的路。

如果我们选择选项 1,我宁愿更改所有缓存管理器以扩展新的基类,而不是发送事件。

我们可以在执行器项目中创建一个新的基类,那么对千分尺的依赖就不再是问题了。我们可以在执行器中实现不同缓存提供程序的所有子类。要使用它,我们需要检查属性“management.metrics.enable”,如果它设置为allcache,则创建指标感知缓存管理器,否则使用默认缓存管理器。

为了实现这一点,最好从 AbstractTransactionAwareCacheManager 进行扩展,原因如下:1)我们可以简单地重写 getMissingCache() 来注册动态创建的缓存。很简单。 2)我们不需要编写任何代码来维护“cacheMap”相关代码。 (参见 AbstractCacheManager) 3)如果用户需要交易感知包装器,我们不需要编写任何代码来装饰交易感知包装器。

然而,Spring Boot非常灵活,用户可以创建自己的缓存配置,可以忽略我们这里的逻辑并创建自己的缓存管理器。因此,我们在这里所做的是提供指标感知的缓存管理器并具有合理的默认初始化配置,但我们不能承诺或限制用户如何使用它。

4

感谢您的建议,但包装CacheManager不是我热衷于做的事情,因为它会更改注册的 bean 类型,并且会影响期望他们正在使用的缓存库类型的用户。我刚刚拒绝了https://github.com/spring-projects/spring-framework/issues/21884,因此现阶段也不能选择该活动。

我想使用 Micrometer 本身探索一些选项。我已经联系了团队,看看我们是否可以朝这个方向做点什么。