Skip to content

Spring Boot Actuator Info 端点详解 📊

什么是 Info 端点?

Spring Boot Actuator 的 info 端点就像是你应用程序的"身份证",它提供了关于应用程序的基本信息。想象一下,当你需要快速了解一个正在运行的应用程序时,你会想知道什么?版本号、构建信息、运行环境等等,这些都是 info 端点能够告诉你的。

NOTE

Info 端点是 Spring Boot Actuator 提供的监控端点之一,主要用于暴露应用程序的元数据信息,帮助运维人员和开发者快速了解应用程序的基本情况。

为什么需要 Info 端点? 🤔

在微服务架构中,我们经常面临这样的问题:

  • 版本混乱:生产环境运行的到底是哪个版本?
  • 环境不明:这个服务运行在什么操作系统上?使用的是哪个 Java 版本?
  • 构建信息缺失:这个版本是什么时候构建的?基于哪个 Git 分支?
  • 资源使用情况:当前进程使用了多少内存?有多少 CPU 核心可用?

Info 端点就是为了解决这些问题而生的!

快速开始 🚀

1. 添加依赖

首先,确保你的项目中包含了 Actuator 依赖:

kotlin
dependencies {
    implementation("org.springframework.boot:spring-boot-starter-actuator")
    implementation("org.springframework.boot:spring-boot-starter-web")
}
xml
<dependencies>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-actuator</artifactId>
    </dependency>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-web</artifactId>
    </dependency>
</dependencies>

2. 配置端点暴露

application.yml 中配置:

yaml
management:
  endpoints:
    web:
      exposure:
        include: info
  endpoint:
    info:
      enabled: true

3. 访问 Info 端点

启动应用后,访问:http://localhost:8080/actuator/info

Info 端点的工作原理 ⚙️

Info 端点通过 InfoContributor 接口收集各种信息。Spring Boot 内置了多个贡献者:

响应结构详解 📋

完整响应示例

当你访问 /actuator/info 时,会得到类似这样的响应:

json
{
  "git": {
    "branch": "main",
    "commit": {
      "id": "df027cf",
      "time": "2025-05-22T20:03:14Z"
    }
  },
  "build": {
    "artifact": "application",
    "version": "1.0.3",
    "group": "com.example"
  },
  "os": {
    "name": "Linux",
    "version": "6.11.0-1014-azure",
    "arch": "amd64"
  },
  "process": {
    "pid": 90556,
    "parentPid": 89245,
    "owner": "runner",
    "memory": {
      "heap": {
        "max": 1610612736,
        "committed": 173015040,
        "used": 80645120,
        "init": 262144000
      },
      "nonHeap": {
        "max": -1,
        "committed": 95682560,
        "used": 93349504,
        "init": 7667712
      },
      "garbageCollectors": [{
        "name": "G1 Young Generation",
        "collectionCount": 15
      }]
    },
    "cpus": 4
  },
  "java": {
    "version": "17.0.15",
    "vendor": {
      "name": "BellSoft"
    },
    "runtime": {
      "name": "OpenJDK Runtime Environment",
      "version": "17.0.15+10-LTS"
    },
    "jvm": {
      "name": "OpenJDK 64-Bit Server VM",
      "vendor": "BellSoft",
      "version": "17.0.15+10-LTS"
    }
  }
}

各部分信息解析

🏗️ Build 信息

包含应用程序的构建相关信息:

字段类型描述
artifactString项目的 artifact ID
groupString项目的 group ID
nameString应用程序名称
versionString应用程序版本
timeVaries构建时间戳

🌿 Git 信息

包含版本控制相关信息:

字段类型描述
branchStringGit 分支名称
commit.idString提交 ID
commit.timeVaries提交时间戳

💻 操作系统信息

包含运行环境的系统信息:

字段类型描述
nameString操作系统名称
versionString操作系统版本
archString系统架构

🔄 进程信息

包含当前 Java 进程的详细信息:

字段类型描述
pidNumber进程 ID
parentPidNumber父进程 ID
ownerString进程所有者
cpusNumber可用 CPU 核心数
memory.heap.*Object堆内存信息
memory.nonHeap.*Object非堆内存信息

☕ Java 信息

包含 Java 运行时环境信息:

字段类型描述
versionStringJava 版本
vendor.nameStringJVM 厂商名称
runtime.nameString运行时名称
jvm.nameStringJVM 名称

实际应用场景 🎯

场景1:版本确认

在生产环境部署后,运维人员可以快速确认部署的版本:

bash
# 快速检查生产环境版本
curl -s http://prod-server:8080/actuator/info | jq '.build.version'
# 输出: "1.0.3"

场景2:问题排查

当应用出现内存问题时,可以查看内存使用情况:

bash
# 检查内存使用情况
curl -s http://localhost:8080/actuator/info | jq '.process.memory.heap'

场景3:环境验证

确认应用运行在正确的环境中:

bash
# 检查运行环境
curl -s http://localhost:8080/actuator/info | jq '{os: .os, java: .java.version}'

自定义 Info 信息 🛠️

方式1:配置文件添加

application.yml 中添加自定义信息:

yaml
info:
  app:
    name: "我的应用程序"
    description: "这是一个示例应用"
    contact:
      email: "[email protected]"
      phone: "123-456-7890"
  team:
    name: "开发团队A"
    lead: "张三"

方式2:自定义 InfoContributor

创建自定义的信息贡献者:

kotlin
@Component
class CustomInfoContributor : InfoContributor {
    
    override fun contribute(builder: Info.Builder) {
        // 添加数据库连接信息
        val dbInfo = mapOf(
            "url" to getDataSourceUrl(),  
            "driver" to "MySQL",  
            "poolSize" to getCurrentPoolSize()  
        )
        
        // 添加缓存信息
        val cacheInfo = mapOf(
            "type" to "Redis",  
            "nodes" to getRedisNodes(),  
            "hitRate" to getCacheHitRate()  
        )
        
        builder.withDetail("database", dbInfo)  
               .withDetail("cache", cacheInfo)  
    }
    
    private fun getDataSourceUrl(): String {
        // 获取数据源URL的逻辑
        return "jdbc:mysql://localhost:3306/mydb"
    }
    
    private fun getCurrentPoolSize(): Int {
        // 获取连接池大小的逻辑
        return 10
    }
    
    private fun getRedisNodes(): List<String> {
        // 获取Redis节点信息的逻辑
        return listOf("redis-1:6379", "redis-2:6379")
    }
    
    private fun getCacheHitRate(): Double {
        // 获取缓存命中率的逻辑
        return 0.85
    }
}

方式3:环境相关的信息贡献者

根据不同环境提供不同信息:

kotlin
@Component
class EnvironmentInfoContributor(
    private val environment: Environment
) : InfoContributor {
    
    override fun contribute(builder: Info.Builder) {
        val activeProfiles = environment.activeProfiles
        val environmentInfo = mapOf(
            "profiles" to activeProfiles.toList(),  
            "environment" to determineEnvironment(activeProfiles),  
            "config" to getEnvironmentConfig()  
        )
        
        builder.withDetail("environment", environmentInfo)  
    }
    
    private fun determineEnvironment(profiles: Array<String>): String {
        return when {
            profiles.contains("prod") -> "生产环境"
            profiles.contains("staging") -> "预发布环境"
            profiles.contains("test") -> "测试环境"
            else -> "开发环境"
        }
    }
    
    private fun getEnvironmentConfig(): Map<String, Any> {
        return mapOf(
            "serverPort" to environment.getProperty("server.port", "8080"),
            "logLevel" to environment.getProperty("logging.level.root", "INFO"),
            "enableDebug" to environment.getProperty("debug", Boolean::class.java, false)
        )
    }
}

安全考虑 🔒

WARNING

Info 端点可能暴露敏感信息,在生产环境中需要特别注意安全配置。

1. 限制访问

yaml
management:
  endpoints:
    web:
      exposure:
        include: info
      base-path: "/management"
  endpoint:
    info:
      enabled: true
  security:
    enabled: true

2. 配置安全认证

kotlin
@Configuration
@EnableWebSecurity
class ActuatorSecurityConfig {
    
    @Bean
    fun securityFilterChain(http: HttpSecurity): SecurityFilterChain {
        return http
            .requestMatchers("/actuator/**")  
            .hasRole("ADMIN")  
            .and()
            .httpBasic()  
            .and()
            .build()
    }
}

3. 过滤敏感信息

kotlin
@Component
class SecureInfoContributor : InfoContributor {
    
    override fun contribute(builder: Info.Builder) {
        // 只暴露必要的信息,避免敏感数据
        val safeInfo = mapOf(
            "version" to getApplicationVersion(),
            "status" to "running",
            "uptime" to getUptime()
            // 不包含数据库密码、API密钥等敏感信息
        )
        
        builder.withDetail("application", safeInfo)
    }
    
    private fun getApplicationVersion(): String = "1.0.0"
    private fun getUptime(): String = "2 days, 3 hours"
}

最佳实践 ✅

1. 合理的信息粒度

TIP

不要暴露过多详细信息,保持信息的简洁性和相关性。

kotlin
// ✅ 好的做法
val buildInfo = mapOf(
    "version" to "1.0.3",
    "timestamp" to "2024-01-15T10:30:00Z"
)

// ❌ 避免的做法
val buildInfo = mapOf(
    "version" to "1.0.3",
    "timestamp" to "2024-01-15T10:30:00Z",
    "buildMachine" to "jenkins-slave-01.internal.company.com",  
    "buildUser" to "jenkins",  
    "internalBuildId" to "BUILD-12345-SECRET"
)

2. 使用缓存优化性能

kotlin
@Component
class CachedInfoContributor : InfoContributor {
    
    @Cacheable("info-cache")  
    override fun contribute(builder: Info.Builder) {
        // 计算密集型的信息收集
        val expensiveInfo = calculateExpensiveMetrics()
        builder.withDetail("metrics", expensiveInfo)
    }
    
    private fun calculateExpensiveMetrics(): Map<String, Any> {
        // 模拟耗时操作
        Thread.sleep(1000)
        return mapOf("calculated" to System.currentTimeMillis())
    }
}

3. 监控和告警

结合监控系统使用 Info 端点:

kotlin
@RestController
class HealthCheckController {
    
    @Autowired
    private lateinit var infoEndpoint: InfoEndpoint
    
    @GetMapping("/api/version")
    fun getCurrentVersion(): ResponseEntity<Map<String, String>> {
        val info = infoEndpoint.info()
        val version = info["build"] as? Map<*, *>
        
        return if (version != null) {
            ResponseEntity.ok(mapOf("version" to version["version"].toString()))  
        } else {
            ResponseEntity.status(HttpStatus.SERVICE_UNAVAILABLE)  
                .body(mapOf("error" to "Version information not available"))
        }
    }
}

故障排查 🔧

常见问题

  1. Info 端点返回空对象
解决方案

检查是否正确配置了 InfoContributor,或者在 application.yml 中添加了 info 配置:

yaml
info:
  app:
    name: "My Application"
    version: "1.0.0"
  1. Git 信息不显示
解决方案

确保构建过程中生成了 git.properties 文件。在 Gradle 中添加:

kotlin
plugins {
    id("com.gorylenko.gradle-git-properties") version "2.4.1"
}
  1. 内存信息显示异常
解决方案

检查 JVM 参数配置,确保有足够的权限访问系统信息:

bash
java -Djava.security.manager=default -jar app.jar
# 移除安全管理器限制
java -jar app.jar

总结 📝

Spring Boot Actuator 的 Info 端点是一个强大而实用的监控工具,它能够:

  • 🎯 快速识别:帮助快速识别应用程序版本和环境信息
  • 🔍 问题排查:提供运行时信息辅助问题诊断
  • 📊 监控集成:与监控系统集成,实现自动化运维
  • 🛡️ 安全可控:通过合理配置保证信息安全

通过合理使用 Info 端点,你可以大大提升应用程序的可观测性和运维效率。记住,好的监控不仅仅是收集数据,更重要的是收集有用的数据! 🚀

IMPORTANT

在生产环境中使用 Info 端点时,务必考虑安全性,避免暴露敏感信息,并配置适当的访问控制。