Spring Boot 2 Actuator 不发布 jvm 指标
Posted
技术标签:
【中文标题】Spring Boot 2 Actuator 不发布 jvm 指标【英文标题】:Spring Boot 2 Actuator doesnt publish jvm metric 【发布时间】:2019-02-08 10:32:57 【问题描述】:我正在运行 Spring Boot 2 应用程序并添加了执行器 spring boot 启动器依赖项。我启用了所有 Web 端点,然后调用:
http://localhost:8080/actuator/metrics
结果是:
"names": ["jdbc.connections.active",
"jdbc.connections.max",
"jdbc.connections.min",
"hikaricp.connections.idle",
"hikaricp.connections.pending",
"hikaricp.connections",
"hikaricp.connections.active",
"hikaricp.connections.creation",
"hikaricp.connections.max",
"hikaricp.connections.min",
"hikaricp.connections.usage",
"hikaricp.connections.timeout",
"hikaricp.connections.acquire"]
但我缺少所有 JVM 统计信息和其他内置指标。我在这里想念什么?我读到的所有内容都说这些指标应该随时可用。
感谢任何提示。
【问题讨论】:
查看代码后的一些发现。也许核心开发人员知道一些事情:由于某种原因 MeterRegistryPostProcessor 不会应用于我的 GraphiteMeterRegistry ,因此没有得到配置。这就是我从阅读(整个)代码中猜到的。但是 GraphiteMeterRegistry 肯定是作为 bean 加载的(如 /actuator/beans 中所示) 我在 Spring Boot v2.0.4.RELEASE 上运行时遇到了完全相同的问题。 启用@EnableGlobalMethodSecurity 时,Spring Boot 2.1.2 出现同样的问题 【参考方案1】:我想与您分享这些发现。问题是第 3 方库(Shiro)和我的配置。 micrometer 的 bean 加载混淆了,导致配置 MicroMeterRegistry(在我的情况下为 PrometheusMeterRegistry)的所需 PostProcessingBean 初始化太晚。
我不知道通过不同的 Bean (PostProcessor) 配置注册表是否明智,这可能会导致我遇到的情况......注册表应该配置自己而不依赖其他可能构建得太晚的 Bean。
【讨论】:
【参考方案2】:万一这种情况发生在其他人身上: 我有一个类似的问题(除了它不是 Graphite 而是 Prometheus,而且我没有使用 Shiro)。
基本上我只有 Hikari 和 HTTP 指标,没有其他指标(没有像 GC 这样的 JVM 指标)。
在找出根本原因之前,我撞了几堵墙:Spring Boot Autoconfigure 中有一个 Hikari 自动配置后处理器急切地检索 MeterRegistry,所以之前所有 Metric bean 都没有时间初始化。
令我惊讶的是,在 Github 中查看这段代码时,我没有找到它。所以我将我的spring-boot-starter-parent
版本从2.0.4.RELEASE
提升到2.1.0.RELEASE
,现在一切正常。我正确地获得了所有指标。
【讨论】:
【参考方案3】:正如我所料,这个问题是由 bean 的加载顺序引起的。
我在项目中使用了 Shiro。
Shiro 的验证方法使用 MyBatis 从数据库中读取数据。
我对MyBatis的Mapper文件使用了@Autowired,导致SpringBoot无法组装Actuator metrics相关的bean(不知道具体是什么原因)。
所以我通过手动组装禁用了 Mapper 文件的自动组装。
代码如下:
public class SpringContextUtil implements ApplicationContextAware
private static ApplicationContext applicationContext;
public void setApplicationContext(ApplicationContext applicationContext)
throws BeansException
SpringContextUtil.applicationContext = applicationContext;
public static ApplicationContext getApplicationContext()
return applicationContext;
public static Object getBean(String beanId) throws BeansException
return applicationContext.getBean(beanId);
然后
StoreMapper userMapper = (UserMapper) SpringContextUtil.getBean("userMapper");
UserModel userModel = userMapper.findUserByName(name);
问题暂时可以解决。这只是权宜之计,但目前我没有更好的办法。
【讨论】:
【参考方案4】:我在/actuator/prometheus中找不到process_update_seconds,所以我花了一些时间来解决我的问题。
我的解决方案:
重写HikariDataSourceMetricsPostProcessor
和MeterRegistryPostProcessor
;
HikariDataSourceMetricsPostProcessor
的排序为 Ordered.HIGHEST_PRECEDENCE + 1;
package org.springframework.boot.actuate.autoconfigure.metrics.jdbc;
...
class HikariDataSourceMetricsPostProcessor implements BeanPostProcessor, Ordered
...
public int getOrder()
return Ordered.HIGHEST_PRECEDENCE + 1;
MeterRegistryPostProcessor
的排序为 Ordered.HIGHEST_PRECEDENCE;
package org.springframework.boot.actuate.autoconfigure.metrics;
...
import org.springframework.core.Ordered;
class MeterRegistryPostProcessor implements BeanPostProcessor, Ordered
...
@Override
public int getOrder()
return Ordered.HIGHEST_PRECEDENCE;
在我的例子中,我使用了 shiro 并使用 jpa 来保存用户会话 ID。我发现MeterRegistryPostProcessor
和HikariDataSourceMetricsPostProcessor
的顺序导致了问题。 MeterRegistry
因为加载顺序没有绑定metirc。
也许我的解决方案会帮助你解决问题。
【讨论】:
【参考方案5】:我有a working sample with Spring Boot, Micrometer, and Graphite 并确认开箱即用的MeterBinder
s 的工作方式如下:
"names" : [ "jvm.memory.max", "process.files.max", "jvm.gc.memory.promoted", "tomcat.cache.hit", "system.load.average.1m", "tomcat.cache.access", "jvm.memory.used", "jvm.gc.max.data.size", "jvm.gc.pause", "jvm.memory.committed", "system.cpu.count", "logback.events", "tomcat.global.sent", "jvm.buffer.memory.used", "tomcat.sessions.created", "jvm.threads.daemon", "system.cpu.usage", "jvm.gc.memory.allocated", "tomcat.global.request.max", "tomcat.global.request", "tomcat.sessions.expired", "jvm.threads.live", "jvm.threads.peak", "tomcat.global.received", "process.uptime", "tomcat.sessions.rejected", "process.cpu.usage", "tomcat.threads.config.max", "jvm.classes.loaded", "jvm.classes.unloaded", "tomcat.global.error", "tomcat.sessions.active.current", "tomcat.sessions.alive.max", "jvm.gc.live.data.size", "tomcat.servlet.request.max", "tomcat.threads.current", "tomcat.servlet.request", "process.files.open", "jvm.buffer.count", "jvm.buffer.total.capacity", "tomcat.sessions.active.max", "tomcat.threads.busy", "my.counter", "process.start.time", "tomcat.servlet.error" ]
注意graphite
分支上的示例,而不是master
分支。
如果你能以你所看到的方式破坏样本,我可以再看看。
【讨论】:
以上是关于Spring Boot 2 Actuator 不发布 jvm 指标的主要内容,如果未能解决你的问题,请参考以下文章
Spring Boot Actuator 的“httptrace”端点在 Spring Boot 2.2.0 中不再存在