繁体   English   中英

Spring Boot Actuator 不带 Spring Boot

[英]Spring Boot Actuator without Spring Boot

我一直在开发 Spring/Spring MVC 应用程序,我希望添加性能指标。 我遇到过 Spring Boot Actuator,它看起来是一个很好的解决方案。 但是我的应用程序不是 Spring Boot 应用程序。 我的应用程序在传统容器中运行 Tomcat 8.

我添加了以下依赖项

// Spring Actuator
compile "org.springframework.boot:spring-boot-starter-actuator:1.2.3.RELEASE"

我创建了以下配置 class。

@EnableConfigurationProperties
@Configuration
@EnableAutoConfiguration
@Profile(value = {"dev", "test"})
@Import(EndpointAutoConfiguration.class)
public class SpringActuatorConfig {

}

我什至按照 StackOverflow 上另一篇文章的建议,在每个配置 class 上添加@EnableConfigurationProperties 然而那并没有起到任何作用。 端点仍未创建并返回 404。

首先让我们澄清一下,如果不使用 Spring Boot,就不能使用 Spring Boot Actuator。

如果没有 Spring Boot,我就无法做到这一点,我错了。 有关如何执行此操作的示例,请参阅 @stefaan-neyts 答案。

我创建了一个示例项目来展示如何使用最少的 Spring Boot 自动配置来转换基本的 SpringMVC 应用程序。

原始来源: http : //www.mkyong.com/spring-mvc/gradle-spring-mvc-web-project-example

转换源: https : //github.com/Pytry/minimal-boot-actuator

我本可以完全删除 dispatcher-servlet.xml 和 web.xml 文件,但我保留它们是为了展示如何执行尽可能少的更改并简化更复杂项目的转换。

这是我进行转换所采取的步骤列表。

转换过程

  • 添加一个用@SpringBootApplication注解的Java配置文件
  • 将 Application 配置文件作为 bean 添加到传统的 xml 配置中(在上下文扫描之后添加)。
  • 将视图解析器移动到应用程序 java 配置中。

    或者,将前缀和后缀添加到 application.properties。 然后,您可以在应用程序中使用 @Value 注入它们,或者将其完全删除并仅使用提供的 Spring Boot 视图解析器。 我和前者一起去了。

  • 从 spring 上下文 xml 中删除了默认上下文侦听器。

    这个很重要! 由于 spring boot 将提供一个,如果您不提供,您将收到“错误侦听器启动”异常。

  • 将 spring boot 插件添加到您的构建脚本依赖项中(我使用的是 gradle)

  • 将 mainClassName 属性添加到构建文件,并设置为空字符串(表示不创建可执行文件)。

  • 修改 spring boot 执行器的依赖项

您可以使用没有弹簧靴的执行器。 将此添加到 pom.xml

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-actuator</artifactId>
    <version>1.3.5.RELEASE</version>
</dependency>

<dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-web</artifactId>
    <version>4.3.5.RELEASE</version>
</dependency>

然后在你的配置类中

@Configuration
@EnableWebMvc
@Import({
        EndpointAutoConfiguration.class , PublicMetricsAutoConfiguration.class , HealthIndicatorAutoConfiguration.class
})
public class MyActuatorConfig {

    @Bean
    @Autowired
    public EndpointHandlerMapping endpointHandlerMapping(Collection<? extends MvcEndpoint> endpoints) {
        return new EndpointHandlerMapping(endpoints);
    }

    @Bean
    @Autowired
    public EndpointMvcAdapter metricsEndPoint(MetricsEndpoint delegate) {
        return new EndpointMvcAdapter(delegate);
    }
}

然后你可以在你的应用程序中看到指标

http://localhost:8085/metrics

执行器终点

尽管在没有 Spring Boot 的情况下使用 Spring Boot 功能不是一个好主意,但这是可能的!

例如,此 Java 配置使 Spring Boot Actuator Metrics 在不使用 Spring Boot 的情况下可用:

import java.util.Collection;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.actuate.autoconfigure.EndpointAutoConfiguration;
import org.springframework.boot.actuate.autoconfigure.PublicMetricsAutoConfiguration;
import org.springframework.boot.actuate.endpoint.MetricsEndpoint;
import org.springframework.boot.actuate.endpoint.mvc.EndpointHandlerMapping;
import org.springframework.boot.actuate.endpoint.mvc.EndpointMvcAdapter;
import org.springframework.boot.actuate.endpoint.mvc.MvcEndpoint;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Import;

@Configuration
@Import({ EndpointAutoConfiguration.class, PublicMetricsAutoConfiguration.class })
public class SpringBootActuatorConfig {

    @Bean
    @Autowired
    public EndpointHandlerMapping endpointHandlerMapping(Collection<? extends MvcEndpoint> endpoints) {
        return new EndpointHandlerMapping(endpoints);
    }

    @Bean
    @Autowired
    public EndpointMvcAdapter metricsEndPoint(MetricsEndpoint delegate) {
        return new EndpointMvcAdapter(delegate);
    }
}

Maven 依赖:

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-actuator</artifactId>
    <version>1.3.5.RELEASE</version>
</dependency>

虽然答案已经被接受,但我想更新我的经验。 我不想使用@SpringBootApplication将我的应用程序转换为 spring boot。 请参阅另一个问题,其中我提到了所需的最低限度代码。

由于我们已经有了 Spring Boot Actuator 2.x,将执行器包含到现有 Spring MVC 项目中的方法可能如下所示:

@Configuration
@Import({
        EndpointAutoConfiguration.class,
        HealthIndicatorAutoConfiguration.class,

        InfoEndpointAutoConfiguration.class,
        HealthEndpointAutoConfiguration.class,

        WebEndpointAutoConfiguration.class,
        ServletManagementContextAutoConfiguration.class,
        ManagementContextAutoConfiguration.class,
})
@EnableConfigurationProperties(CorsEndpointProperties.class)
class ActuatorConfiguration {

    @Bean //taken from WebMvcEndpointManagementContextConfiguration.class
    public WebMvcEndpointHandlerMapping webEndpointServletHandlerMapping(WebEndpointsSupplier webEndpointsSupplier,
                                                                         ServletEndpointsSupplier servletEndpointsSupplier, ControllerEndpointsSupplier controllerEndpointsSupplier,
                                                                         EndpointMediaTypes endpointMediaTypes, CorsEndpointProperties corsProperties,
                                                                         WebEndpointProperties webEndpointProperties) {
        List<ExposableEndpoint<?>> allEndpoints = new ArrayList<>();
        Collection<ExposableWebEndpoint> webEndpoints = webEndpointsSupplier.getEndpoints();
        allEndpoints.addAll(webEndpoints);
        allEndpoints.addAll(servletEndpointsSupplier.getEndpoints());
        allEndpoints.addAll(controllerEndpointsSupplier.getEndpoints());
        EndpointMapping endpointMapping = new EndpointMapping(webEndpointProperties.getBasePath());
        return new WebMvcEndpointHandlerMapping(endpointMapping, webEndpoints, endpointMediaTypes,
                corsProperties.toCorsConfiguration(),
                new EndpointLinksResolver(allEndpoints, webEndpointProperties.getBasePath()));
    }

    @Bean
    DispatcherServletPath dispatcherServletPath() {
        return () -> "/";
    }

}

我确实包括

    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-actuator-autoconfigure</artifactId>
        <version>2.1.18.RELEASE</version>
    </dependency>

为了与我一直使用的基线 Spring 版本兼容 (5.1.19.RELEASE)

如果要使用插入其中的组件,则需要将应用程序转换为 Spring Boot。 您需要查看的 Spring Boot 文档下有一个名为 Convert an existing application to Spring Boot 的部分。 我自己没有这样做,但我使用 Spring Boot,它的配置相对简单,所以希望你能从这里得到它。

如果您的目标是为 Prometheus aka OpenMetrics 创建一个具有指标的端点,您可以使用与 Spring 框架兼容的Prometheus JVM 客户端

添加依赖:

    <dependency>
      <groupId>io.prometheus</groupId>
      <artifactId>simpleclient_servlet</artifactId>
      <version>0.16.0</version>
    </dependency>

要收集请求指标,请在web-app/WEB-INF/web.xml中添加为第一个过滤器:

  <filter>
    <filter-name>prometheusFilter</filter-name>
    <filter-class>io.prometheus.client.filter.MetricsFilter</filter-class>
    <init-param>
      <param-name>metric-name</param-name>
      <param-value>webapp_metrics_filter</param-value>
    </init-param>
  </filter>
  <filter-mapping>
    <filter-name>prometheusFilter</filter-name>
    <url-pattern>/*</url-pattern>
  </filter-mapping>

要将指标公开为 HTTP 端点,请添加 servlet:

  <servlet>
    <servlet-name>prometheus</servlet-name>
    <servlet-class>io.prometheus.client.exporter.MetricsServlet</servlet-class>
  </servlet>
  <servlet-mapping>
    <servlet-name>prometheus</servlet-name>
    <url-pattern>/metrics</url-pattern>
  </servlet-mapping>

之后,您可以在/metrics端点上看到指标。

时间流逝,我们有 Spring 6、SpringBoot 3、JakartaEE 作为基准,但人们仍在寻求向遗留 spring 应用程序添加执行器。 所以一个小的更新:spring + 没有 spring-boot 的执行器。实际上变化不大(并且已经指出了变化)。

依赖项

    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-webmvc</artifactId>
        <version>6.0.3</version>
    </dependency>
    <dependency>
       <groupId>jakarta.servlet</groupId>
       <artifactId>jakarta.servlet-api</artifactId>
       <version>6.0.0</version>
       <scope>provided</scope>
    </dependency>
    
    <dependency>
       <groupId>org.springframework.boot</groupId>
       <artifactId>spring-boot-actuator-autoconfigure</artifactId>
       <version>3.0.1</version>
    </dependency>

执行器配置

@Configuration
@ImportAutoConfiguration({
    EndpointAutoConfiguration.class,
    WebEndpointAutoConfiguration.class,
    ServletManagementContextAutoConfiguration.class,
    ManagementContextAutoConfiguration.class,

    HealthContributorAutoConfiguration.class,

    InfoEndpointAutoConfiguration.class,
    HealthEndpointAutoConfiguration.class,

    HeapDumpWebEndpointAutoConfiguration.class,
    ThreadDumpEndpointAutoConfiguration.class,
    LoggersEndpointAutoConfiguration.class,
    PrometheusMetricsExportAutoConfiguration.class,
})
@EnableConfigurationProperties(CorsEndpointProperties.class)
class ActuatorConfiguration {

    @Bean //taken from WebMvcEndpointManagementContextConfiguration.class
    public WebMvcEndpointHandlerMapping webEndpointServletHandlerMapping(WebEndpointsSupplier webEndpointsSupplier,
        ServletEndpointsSupplier servletEndpointsSupplier, ControllerEndpointsSupplier controllerEndpointsSupplier,
        EndpointMediaTypes endpointMediaTypes, CorsEndpointProperties corsProperties,
        WebEndpointProperties webEndpointProperties) {
        List<ExposableEndpoint<?>> allEndpoints = new ArrayList<>();
        Collection<ExposableWebEndpoint> webEndpoints = webEndpointsSupplier.getEndpoints();
        allEndpoints.addAll(webEndpoints);
        allEndpoints.addAll(servletEndpointsSupplier.getEndpoints());
        allEndpoints.addAll(controllerEndpointsSupplier.getEndpoints());
        EndpointMapping endpointMapping = new EndpointMapping(webEndpointProperties.getBasePath());
        return new WebMvcEndpointHandlerMapping(endpointMapping,
            webEndpoints,
            endpointMediaTypes,
            corsProperties.toCorsConfiguration(),
            new EndpointLinksResolver(allEndpoints, webEndpointProperties.getBasePath()),
            true);
    }

    @Bean
    DispatcherServletPath dispatcherServletPath() {
        return () -> WebInitializer.APPLICATION_ROOT;
    }

}

该示例很容易直接从 maven jetty 插件 ( mvn jetty:run-war ) 运行。

            <plugin>
                <groupId>org.eclipse.jetty</groupId>
                <artifactId>jetty-maven-plugin</artifactId>
                <version>11.0.13</version>
            </plugin>

最后的结果

你犯了一个错误,没有在你的代码中引入 @springboot 注释。当你添加 @springboot 时,编译器会自动将其视为引导程序,并为其添加所需的依赖文件和执行器依赖文件

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM