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过滤器:优先级更高,可更早拦截请求减少无效资源消耗,核心逻辑示例:
需在Spring Boot启动类上添加@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); } }@ServletComponentScan注解激活自定义过滤器。 - Spring MVC拦截器:适合已经统一做了拦截器逻辑的项目,直接在preHandle阶段判断状态返回错误响应即可。
3. 日志溢出优化
在全局异常处理器@RestControllerAdvice中新增对SQLException、JDBCConnectionException等数据库连接异常的捕获逻辑,若当前DB_AVAILABLE已经为false,只打印单行关键告警信息,不输出完整栈追踪,避免短时间内产生大量日志打满磁盘。
可选优化点
- 在
DB_AVAILABLE状态切换(可用→不可用、不可用→可用)时,主动触发告警通知,方便运维快速感知故障 - 调低Hikari的
connectionTimeout参数,避免请求长时间等待数据库连接拖垮应用线程池 - 非核心读请求可配置降级逻辑,状态异常时直接返回缓存数据,提升可用性
内容的提问来源于stack exchange,提问作者Nabor
相关产品推荐
相关产品推荐

