簡體   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