You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多
文档控制台
免费开始使用

Spring Actuator健康检查:如何验证数据库活跃连接并自定义状态

Custom Spring Health Check for App + Active Database Connection Validation

Got it, let's tackle this problem step by step. You've already started with a custom health check class, and now you need to integrate active database connection validation into it while aligning with your desired status rules. Here's how to do it properly in Spring Boot:

Core Approach

Spring Boot's Actuator uses HealthIndicator beans to expose health status. We'll extend this to:

  1. First verify your application's core running state
  2. Then validate that an active, working database connection exists
  3. Combine both results to return the correct UP/DOWN status as per your requirements

Option 1: Build Database Validation from Scratch

If you want full control over the database check logic, inject a DataSource and directly validate connections:

@Component
public class AppAndDbHealthCheck implements HealthIndicator {

    private final DataSource dataSource;

    // Constructor injection (preferred over @Autowired in Spring)
    public AppAndDbHealthCheck(DataSource dataSource) {
        this.dataSource = dataSource;
    }

    @Override
    public Health health() {
        // Step 1: Check if your application's core components are running
        boolean appIsHealthy = verifyApplicationCoreState();
        
        if (!appIsHealthy) {
            return Health.down()
                    .withDetail("status", "Application core components not initialized")
                    .build();
        }

        // Step 2: Check for active, valid database connection
        boolean dbConnectionIsValid = verifyActiveDbConnection();
        
        if (dbConnectionIsValid) {
            return Health.up()
                    .withDetail("app_status", "running")
                    .withDetail("db_status", "active connection confirmed")
                    .build();
        } else {
            return Health.down()
                    .withDetail("app_status", "running")
                    .withDetail("status", "No active database connection available")
                    .build();
        }
    }

    private boolean verifyApplicationCoreState() {
        // Replace this with your actual app health check logic
        // Example: Check if critical services/beans are initialized
        return true; // Return false if app is in a broken state
    }

    private boolean verifyActiveDbConnection() {
        // Try to get a connection and validate it
        try (Connection connection = dataSource.getConnection()) {
            // Validate connection with a 2-second timeout
            return connection.isValid(2);
            
            // Alternative: Execute a simple test query for stricter validation
            // try (Statement stmt = connection.createStatement()) {
            //     return stmt.execute("SELECT 1");
            // }
        } catch (SQLException e) {
            // Connection failed or is invalid
            return false;
        }
    }
}

Option 2: Reuse Spring's Built-in DataSourceHealthIndicator

Spring Boot already has a DataSourceHealthIndicator that handles database validation out of the box. You can inject it into your custom check to avoid reinventing the wheel:

@Component
public class AppAndDbHealthCheck implements HealthIndicator {

    private final DataSourceHealthIndicator dbHealthIndicator;

    public AppAndDbHealthCheck(DataSourceHealthIndicator dbHealthIndicator) {
        this.dbHealthIndicator = dbHealthIndicator;
    }

    @Override
    public Health health() {
        // Step 1: Check application state first
        boolean appIsHealthy = verifyApplicationCoreState();
        if (!appIsHealthy) {
            return Health.down().withDetail("reason", "Application is not running properly").build();
        }

        // Step 2: Delegate database check to Spring's built-in indicator
        Health dbHealth = dbHealthIndicator.health();
        if (dbHealth.getStatus() == Status.UP) {
            return Health.up()
                    .withDetail("app_status", "running")
                    .withDetail("db_status", "active")
                    .build();
        } else {
            return Health.down()
                    .withDetail("app_status", "running")
                    .withDetail("db_issues", dbHealth.getDetails())
                    .build();
        }
    }

    private boolean verifyApplicationCoreState() {
        // Your custom app health logic here
        return true;
    }
}

Configuration & Testing

  1. Enable Actuator Endpoints: Make sure you have these properties in application.properties/application.yml to expose the health endpoint:
    management.endpoints.web.exposure.include=health
    management.endpoint.health.show-details=always
    
  2. Test Your Scenarios:
    • App running, DB down: Stop your database, hit http://<your-app-url>/actuator/health → returns DOWN with details about DB failure
    • App down, DB running: Stop the app entirely → health endpoint returns 503 (or is unreachable)
    • Both running: Health endpoint returns UP with positive details for app and DB

内容的提问来源于stack exchange,提问作者Ron Badur

火山引擎 最新活动