Spring Boot 2 Actuator 不发布 jvm 指标

Spring Boot 2 Actuator doesnt publish jvm metric

我是 运行 一个 Spring Boot 2 应用程序并添加了执行器 spring boot starter 依赖项。我启用了所有网络端点,然后调用:

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 统计信息和其他内置指标。我在这里错过了什么?我读到的所有内容都说这些指标应该随时可用。

感谢任何提示。

我有 a working sample with Spring Boot, Micrometer, and Graphite 并确认开箱即用的 MeterBinder 工作如下:

{
  "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 分支上的示例。

如果你能按照你看到的方式分解样本,我可以再看一眼。

我想与您分享我的发现。问题是第 3 方库 (Shiro) 和我的配置。 Micrometer 的 bean 加载混淆了,导致配置 MicroMeterRegistry(在我的例子中是 PrometheusMeterRegistry)所需的 PostProcessingBean 初始化太晚。

我不知道通过不同的 Bean(后处理器)配置 Registry 是否明智,这会导致我遇到的情况......Registry 应该自行配置而不依赖其他可能构建的 Bean晚了。

不出所料,这个问题是bean的加载顺序引起的

我在项目中使用了Shiro

Shiro的验证方式是使用MyBatis从数据库中读取数据

MyBatis的Mapper文件使用了@Autowired,导致Actuator metrics相关的bean无法被SpringBoot组装(不知道具体是什么原因) .

所以我禁用了手动组装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);

问题暂时可以解决。这只是权宜之计,但目前我没有更好的办法。

万一这件事发生在其他人身上: 我遇到了类似的问题(除了它不是 Graphite 而是 Prometheus,而且我没有使用 Shiro)。

基本上我只有 Hikari 和 HTTP 指标,没有别的(没有像 GC 这样的 JVM 指标)。

在找出根本原因之前,我用头撞了几面墙:Spring 引导自动配置中有一个 Hikari 自动配置 post 处理器急切地检索了一个 MeterRegistry,所以所有 Metric bean 都没有之前有时间初始化。

令我惊讶的是,在 Github 中查看此代码时我没有找到它。所以我将我的 spring-boot-starter-parent 版本从 2.0.4.RELEASE 提高到 2.1.0.RELEASE,现在一切正常。我正确地获得了所有指标。

我在/actuator/prometheus中找不到process_update_seconds,所以我花了一些时间来解决我的问题。

我的解决方案:

重写HikariDataSourceMetricsPostProcessorMeterRegistryPostProcessor

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。我发现 MeterRegistryPostProcessorHikariDataSourceMetricsPostProcessor 的顺序导致了问题。 MeterRegistry 因为加载顺序没有绑定 metirc。

也许我的解决方案可以帮助您解决问题。