You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Spring Boot中如何监听数据库可用/不可用状态变更事件?

实现方案

1. Hikari连接池健康状态监听实现

Hikari本身没有内置的断连/恢复事件回调,可通过以下两种方案实现状态检测:

  • 扩展Hikari的HealthCheckRegistry自定义健康检查
    启用Hikari健康检查能力,在检测逻辑中更新全局状态标记,代码示例:
    @Configuration
    public class HikariConfig {
        // 全局数据库可用状态标记,原子类保证线程安全
        public static final AtomicBoolean DB_AVAILABLE = new AtomicBoolean(true);
    
        @Bean
        public HikariDataSource dataSource() {
            HikariConfig config = new HikariConfig();
            // 常规数据源配置(地址、用户名、密码等)省略
    
            // 注册自定义连接健康检查
            HealthCheckRegistry healthCheckRegistry = new HealthCheckRegistry();
            healthCheckRegistry.register("db-connectivity-check", () -> {
                try (Connection conn = config.getDataSource().getConnection()) {
                    boolean valid = conn.isValid(1); // 1秒超时校验连接有效性
                    DB_AVAILABLE.set(valid);
                    return HealthCheckResult.healthCheckResultHealthy();
                } catch (SQLException e) {
                    DB_AVAILABLE.set(false);
                    return HealthCheckResult.healthCheckResultUnhealthy("连接失败:" + e.getMessage());
                }
            });
            config.setHealthCheckRegistry(healthCheckRegistry);
            // 配置连接存活检测参数,加快无效连接淘汰
            config.setValidationTimeout(3000);
            config.setKeepaliveTime(30000);
            config.setConnectionTestQuery("SELECT 1");
            return new HikariDataSource(config);
        }
    }
    
  • 轻量定时检测方案
    若不需要启用Hikari健康检查,可通过Spring自带的@Scheduled注解配置每2-3秒执行一次连接有效性校验,直接更新全局DB_AVAILABLE状态即可,实现逻辑更简洁。

2. 全局请求拦截统一返回错误码

可根据项目架构二选一实现:

  • Servlet过滤器:优先级更高,可更早拦截请求减少无效资源消耗,核心逻辑示例:
    @WebFilter(urlPatterns = "/*")
    public class DbStatusFilter implements Filter {
        @Override
        public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
            if (!HikariConfig.DB_AVAILABLE.get()) {
                response.setContentType("application/json;charset=utf-8");
                // 此处返回你项目约定的规范错误码即可
                response.getWriter().write(JSON.toJSONString(CommonResult.error(503, "数据库服务暂不可用,请稍后重试")));
                return;
            }
            chain.doFilter(request, response);
        }
    }
    
    需在Spring Boot启动类上添加@ServletComponentScan注解激活自定义过滤器。
  • Spring MVC拦截器:适合已经统一做了拦截器逻辑的项目,直接在preHandle阶段判断状态返回错误响应即可。

3. 日志溢出优化

在全局异常处理器@RestControllerAdvice中新增对SQLException、JDBCConnectionException等数据库连接异常的捕获逻辑,若当前DB_AVAILABLE已经为false,只打印单行关键告警信息,不输出完整栈追踪,避免短时间内产生大量日志打满磁盘。

可选优化点

  • 在DB_AVAILABLE状态切换(可用→不可用、不可用→可用)时,主动触发告警通知,方便运维快速感知故障
  • 调低Hikari的connectionTimeout参数,避免请求长时间等待数据库连接拖垮应用线程池
  • 非核心读请求可配置降级逻辑,状态异常时直接返回缓存数据,提升可用性

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.26 17:45:04