无弹簧启动的弹簧启动器

我一直在开发一个 Spring/Spring MVC 应用程序,正在寻找添加性能指标的方法。我已经遇到了弹簧启动执行器,它看起来像一个伟大的解决方案。但是,我的应用程序不是 SpringBoot 应用程序。我的应用程序在传统容器 Tomcat 8中运行。

我添加了以下依赖项

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

我创建了以下配置类。

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


}

根据 StackOverflow 上另一篇文章的建议,我甚至在每个配置类上都添加了 @EnableConfigurationProperties。然而这并没有起到什么作用。仍然没有创建端点并返回404。

39570 次浏览

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

我错了,没有 Spring Boot 我做不到 举例说明如何做。

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

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

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

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

下面是我采取的转换步骤的列表。

转换过程

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

    或者,将前缀和后缀添加到 application.properties。 然后可以在应用程序中注入@Value,或者完全删除它,只需使用提供的 Spring 引导视图解析器即可。 我选择了前者

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

    这很重要! 因为 Spring boot 会提供一个,如果你不这样做,你会得到一个“错误侦听器启动”异常。

  • 将 Spring 引导插件添加到构建脚本依赖项中(我使用的是 gradle)

  • 向生成文件添加 mainClassName 属性,并将其设置为空 String (表示不创建可执行文件)。

  • 修改弹簧启动执行器的依赖项

虽然这个答案已经被接受了,我还是想更新一下我的经验。我不想使用 @SpringBootApplication将应用程序转换为弹簧启动。参考 另一个问题,在那里我已经提到了最低限度的代码要求。

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

例如,这个 Java 配置使得不使用 Spring 引导的 Spring 引导执行器度量可用:

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>

您可以使用驱动器没有弹簧启动。 将其添加到 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

Actutaor end point

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

正如我们已经有了 Spring Boot Acutator 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)兼容

如果您的目标是创建一个端点,其中包含 Prometheus 又名 OpenMetrics 的度量,那么您可以使用与 Spring 框架兼容的 普罗米修斯 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端点上的指标。