Appearance
Spring Boot Actuator 构建信息集成详解 🏗️
什么是 Spring Boot Actuator 构建信息?
Spring Boot Actuator 是 Spring Boot 提供的生产就绪功能模块,它可以帮助我们监控和管理应用程序。其中,构建信息(Build Info)是 Actuator 提供的一个重要功能,它能够展示应用程序的构建相关信息。
NOTE
构建信息功能需要在项目的 META-INF
目录下存在 build-info.properties
文件才能正常工作。
为什么需要构建信息? 🤔
在实际的生产环境中,我们经常遇到这样的问题:
- 版本混乱:不知道当前运行的是哪个版本的应用
- 构建追踪困难:无法快速确定应用的构建时间和构建环境
- 问题排查复杂:出现问题时难以定位具体的构建版本
构建信息功能就是为了解决这些痛点而设计的。它让我们能够:
核心价值
- ✅ 版本透明化:清楚知道当前运行的应用版本
- ✅ 构建可追溯:记录构建时间、Java 版本等关键信息
- ✅ 问题快速定位:通过构建信息快速排查问题
- ✅ 运维友好:为运维人员提供关键的应用元数据
工作原理解析 ⚙️
让我们通过时序图来理解构建信息的生成和使用过程:
Maven 插件配置详解 🔧
基础配置
首先,让我们看看最基本的配置:
xml
<project>
<modelVersion>4.0.0</modelVersion>
<artifactId>my-spring-boot-app</artifactId>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<executions>
<execution>
<goals>
<goal>build-info</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
</project>
xml
<project>
<modelVersion>4.0.0</modelVersion>
<artifactId>my-spring-boot-app</artifactId>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<executions>
<execution>
<goals>
<goal>build-info</goal>
</goals>
<configuration>
<!-- 添加自定义属性 -->
<additionalProperties>
<encoding.source>UTF-8</encoding.source>
<encoding.reporting>UTF-8</encoding.reporting>
<java.version>${java.version}</java.version>
<spring.boot.version>${spring.boot.version}</spring.boot.version>
</additionalProperties>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
</project>
高级配置选项
让我们深入了解各个配置参数:
完整的高级配置示例
xml
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<executions>
<execution>
<goals>
<goal>build-info</goal>
</goals>
<configuration>
<!-- 自定义输出文件位置 -->
<outputFile>${project.build.outputDirectory}/META-INF/build-info.properties</outputFile>
<!-- 排除某些默认属性 -->
<excludeInfoProperties>
<excludeInfoProperty>time</excludeInfoProperty>
</excludeInfoProperties>
<!-- 添加额外属性 -->
<additionalProperties>
<encoding.source>UTF-8</encoding.source>
<encoding.reporting>UTF-8</encoding.reporting>
<java.version>${java.version}</java.version>
<spring.boot.version>${spring.boot.version}</spring.boot.version>
<git.branch>${git.branch}</git.branch>
<git.commit.id>${git.commit.id}</git.commit.id>
<build.user>${user.name}</build.user>
<build.environment>${env.BUILD_ENV}</build.environment>
</additionalProperties>
<!-- 跳过构建信息生成 -->
<skip>false</skip>
<!-- 自定义构建时间 -->
<time>${maven.build.timestamp}</time>
</configuration>
</execution>
</executions>
</plugin>
生成的构建信息文件 📄
执行构建后,会在 target/classes/META-INF/build-info.properties
生成如下内容:
properties
# 默认生成的属性
build.artifact=my-spring-boot-app
build.group=com.example
build.name=My Spring Boot Application
build.time=2024-01-15T10:30:45.123Z
build.version=1.0.0
# 自定义添加的属性(都会加上 build. 前缀)
build.encoding.source=UTF-8
build.encoding.reporting=UTF-8
build.java.version=17
build.spring.boot.version=3.2.0
IMPORTANT
注意:所有通过 additionalProperties
添加的属性都会自动加上 build.
前缀。
Kotlin + Spring Boot 实战示例 🚀
让我们看看如何在 Kotlin 项目中使用构建信息:
1. 创建构建信息服务
kotlin
@Service
class BuildInfoService(
private val buildProperties: BuildProperties? = null
) {
/**
* 获取应用构建信息
*/
fun getBuildInfo(): Map<String, Any> {
return buildProperties?.let { props ->
mapOf(
"name" to props.name,
"version" to props.version,
"artifact" to props.artifact,
"group" to props.group,
"time" to props.time,
// 获取自定义属性
"javaVersion" to (props.get("java.version") ?: "Unknown"),
"springBootVersion" to (props.get("spring.boot.version") ?: "Unknown")
)
} ?: mapOf("error" to "Build info not available")
}
/**
* 检查是否为生产环境构建
*/
fun isProductionBuild(): Boolean {
return buildProperties?.get("build.environment") == "production"
}
}
2. 创建构建信息控制器
kotlin
@RestController
@RequestMapping("/api/build")
class BuildInfoController(
private val buildInfoService: BuildInfoService
) {
/**
* 获取构建信息API
*/
@GetMapping("/info")
fun getBuildInfo(): ResponseEntity<Map<String, Any>> {
val buildInfo = buildInfoService.getBuildInfo()
return ResponseEntity.ok(buildInfo)
}
/**
* 健康检查,包含版本信息
*/
@GetMapping("/health")
fun healthCheck(): ResponseEntity<Map<String, Any>> {
val buildInfo = buildInfoService.getBuildInfo()
return ResponseEntity.ok(mapOf(
"status" to "UP",
"version" to buildInfo["version"],
"buildTime" to buildInfo["time"],
"timestamp" to System.currentTimeMillis()
))
}
}
3. 自定义 Actuator Info 贡献者
kotlin
@Component
class CustomInfoContributor : InfoContributor {
override fun contribute(builder: Info.Builder) {
// 添加自定义运行时信息
builder.withDetail("runtime", mapOf(
"activeProfiles" to getActiveProfiles(),
"jvmVersion" to System.getProperty("java.version"),
"osName" to System.getProperty("os.name"),
"availableProcessors" to Runtime.getRuntime().availableProcessors(),
"maxMemory" to "${Runtime.getRuntime().maxMemory() / 1024 / 1024} MB"
))
// 添加应用特定信息
builder.withDetail("application", mapOf(
"description" to "My awesome Spring Boot application",
"features" to listOf("REST API", "Database", "Caching"),
"maintainer" to "Development Team"
))
}
private fun getActiveProfiles(): List<String> {
// 这里可以注入 Environment 来获取激活的配置文件
return listOf("default") // 简化示例
}
}
实际应用场景 💡
场景1:生产环境版本确认
kotlin
@Component
class DeploymentValidator(
private val buildInfoService: BuildInfoService
) {
@EventListener(ApplicationReadyEvent::class)
fun validateDeployment() {
val buildInfo = buildInfoService.getBuildInfo()
logger.info("=== 应用部署信息 ===")
logger.info("应用名称: ${buildInfo["name"]}")
logger.info("版本号: ${buildInfo["version"]}")
logger.info("构建时间: ${buildInfo["time"]}")
logger.info("Java版本: ${buildInfo["javaVersion"]}")
// 生产环境额外检查
if (buildInfoService.isProductionBuild()) {
logger.warn("🚀 生产环境部署确认完成!")
}
}
companion object {
private val logger = LoggerFactory.getLogger(DeploymentValidator::class.java)
}
}
场景2:API 响应中包含版本信息
kotlin
@RestControllerAdvice
class GlobalResponseHandler {
@Autowired
private lateinit var buildProperties: BuildProperties
/**
* 为所有API响应添加版本信息
*/
@ModelAttribute("apiVersion")
fun addVersionInfo(): String {
return buildProperties.version
}
}
// 使用示例
@RestController
class UserController {
@GetMapping("/users")
fun getUsers(@ModelAttribute("apiVersion") version: String): ResponseEntity<Any> {
return ResponseEntity.ok(mapOf(
"data" to listOf(/* 用户数据 */),
"meta" to mapOf(
"apiVersion" to version,
"timestamp" to System.currentTimeMillis()
)
))
}
}
配置参数详解 ⚙️
参数名 | 类型 | 默认值 | 说明 |
---|---|---|---|
additionalProperties | Map | - | 添加到构建信息中的额外属性 |
excludeInfoProperties | List | - | 要排除的属性列表 |
outputFile | File | META-INF/build-info.properties | 输出文件位置 |
skip | boolean | false | 是否跳过构建信息生成 |
time | String | ${project.build.outputTimestamp} | 构建时间 |
TIP
使用 excludeInfoProperties
可以排除敏感信息,比如在某些环境下不想暴露构建时间。
常见问题与解决方案 ⚠️
问题1:构建信息不显示
常见原因
- Maven 插件配置错误
build-info.properties
文件未生成- Actuator 依赖缺失
解决方案:
kotlin
// 1. 确保添加了 Actuator 依赖
// build.gradle.kts
dependencies {
implementation("org.springframework.boot:spring-boot-starter-actuator")
}
// 2. 检查 application.yml 配置
// application.yml
management:
endpoints:
web:
exposure:
include: info # [!code highlight]
info:
build:
enabled: true # [!code highlight]
问题2:自定义属性未显示
xml
<!-- 错误配置 -->
<additionalProperties>
<property name="custom.value">test</property>
</additionalProperties>
<!-- 正确配置 -->
<additionalProperties>
<custom.value>test</custom.value>
</additionalProperties>
问题3:构建时间格式问题
xml
<!-- 自定义时间格式 -->
<configuration>
<time>2024-01-15T10:30:45.123Z</time>
<!-- 或者禁用时间 -->
<time>off</time>
</configuration>
最佳实践建议 ⭐
版本管理:
xml<additionalProperties> <git.branch>${git.branch}</git.branch> <git.commit.id>${git.commit.id}</git.commit.id> </additionalProperties>
环境区分:
xml<additionalProperties> <build.environment>${env.BUILD_ENV}</build.environment> <build.profile>${spring.profiles.active}</build.profile> </additionalProperties>
安全考虑:
xml<excludeInfoProperties> <excludeInfoProperty>build.user</excludeInfoProperty> <excludeInfoProperty>build.machine</excludeInfoProperty> </excludeInfoProperties>
总结 🎉
Spring Boot Actuator 的构建信息功能为我们提供了强大的应用元数据管理能力。通过合理配置和使用,我们可以:
- 🎯 提升运维效率:快速识别应用版本和构建信息
- 🔍 简化问题排查:通过构建信息快速定位问题版本
- 📊 增强监控能力:为监控系统提供丰富的应用元数据
- 🛡️ 保障生产安全:确保部署的是正确版本的应用
NOTE
构建信息功能虽然简单,但在实际的生产环境中却是不可或缺的。它就像应用的"身份证",让我们随时能够了解应用的"出身"和"履历"。
记住,好的构建信息配置不仅能帮助开发团队,更能为运维团队提供宝贵的应用洞察! 🚀