当前位置: 首页 > news >正文

SpringBoot定时监控数据库状态

1.application.properties配置文件

# config for mysql
spring.datasource.url = jdbc\:mysql\://127.0.0.1\:3306/数据库名?characterEncoding\=utf8&useSSL\=false
spring.datasource.username = 账号
spring.datasource.password = 密码
spring.datasource.validation-query= SELECT 1
spring.jpa.properties.hibernate.dialect =org.hibernate.dialect.MySQL5Dialect
#spring.datasource.druid.driver-class-name=com.mysql.cj.jdbc.driver
# ================ 重连配置 ================
# 最大重试次数
spring.datasource.druid.connection-error-retry-attempts=10
# 重试间隔时间(毫秒)
spring.datasource.druid.time-between-connect-error-millis=10000
# 获取连接失败后中断
spring.datasource.druid.break-after-acquire-failure=false# 自定义监控配置
monitoring.database.enabled=true
#30秒检查一次
monitoring.database.interval=30000
#5秒超时
monitoring.database.connection-timeout=5000

2.引入对应依赖

          <dependency><groupId>mysql</groupId><artifactId>mysql-connector-java</artifactId><version>8.0.33</version><!-- 明确排除旧版依赖冲突 --><exclusions><exclusion><groupId>mysql</groupId><artifactId>mysql-connector-java</artifactId></exclusion></exclusions></dependency><!-- Druid 连接池 --><dependency><groupId>com.alibaba</groupId><artifactId>druid-spring-boot-starter</artifactId><version>1.2.16</version></dependency>
<!-- Spring Actuator for Health Checks --><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-actuator</artifactId></dependency>
<!-- 内置的有Schedul的依赖 --><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId></dependency>

3.代码实现

package com.dianju.signatureServer;import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import srvSeal.SrvSealUtil;import javax.annotation.PostConstruct;
import java.sql.*;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.concurrent.atomic.AtomicLong;@RestController
@RequestMapping("/monitorservice")
public class MonitorController {private final Logger log = LoggerFactory.getLogger(this.getClass());@Value("${spring.datasource.url}")private String jdbcUrl;@Value("${spring.datasource.username}")private String username;@Value("${spring.datasource.password}")private String password;@Value("${spring.datasource.validation-query}")private String validationQuery;@Value("${monitoring.database.interval}")private long checkInterval;@Value("${monitoring.database.connection-timeout}")private int connectionTimeout;// 状态跟踪变量private final AtomicInteger consecutiveFailures = new AtomicInteger(0);private final AtomicLong lastFailureTime = new AtomicLong(0);private final AtomicLong lastSuccessTime = new AtomicLong(System.currentTimeMillis());@Autowiredprivate SrvSealUtil srvSealUtil;@PostConstructpublic void init() {try {// 显式加载MySQL驱动Class.forName("com.mysql.cj.jdbc.Driver");log.info("✅ MySQL驱动加载成功");// 打印配置信息log.info("数据库监控配置:");log.info("连接URL: {}", jdbcUrl);log.info("用户名: {}", username);log.info("验证查询: {}", validationQuery);log.info("监控间隔: {}ms", checkInterval);log.info("连接超时: {}ms", connectionTimeout);} catch (ClassNotFoundException e) {log.error("❌ 加载MySQL驱动失败", e);throw new RuntimeException("数据库驱动加载失败", e);}}@Scheduled(fixedRateString = "${monitoring.database.interval}")public void monitorDatabase() {long startTime = System.currentTimeMillis();boolean isHealthy = checkDatabaseHealth();long responseTime = System.currentTimeMillis() - startTime;if (isHealthy) {handleSuccess(responseTime);} else {handleFailure();}}private boolean checkDatabaseHealth() {try (Connection conn = DriverManager.getConnection(buildConnectionUrl(),username,password)) {try (Statement stmt = conn.createStatement();ResultSet rs = stmt.executeQuery(validationQuery)) {return rs.next() && rs.getInt(1) == 1;}} catch (Exception e) {log.error("❌ 数据库健康检查失败", e);return false;}}// 正确构建带超时的连接URLprivate String buildConnectionUrl() {StringBuilder urlBuilder = new StringBuilder(jdbcUrl);if (jdbcUrl.contains("?")) {urlBuilder.append("&connectTimeout=").append(connectionTimeout);} else {urlBuilder.append("?connectTimeout=").append(connectionTimeout);}return urlBuilder.toString();}private void handleSuccess(long responseTime) {// 重置失败计数器consecutiveFailures.set(0);// 更新最后成功时间lastSuccessTime.set(System.currentTimeMillis());// 如果之前有失败记录,输出恢复信息if (lastFailureTime.get() > 0) {long downTime = System.currentTimeMillis() - lastFailureTime.get();log.info("\n🔥 数据库恢复可用! 宕机时长: {}秒\n", downTime / 1000);// 重置失败时间戳lastFailureTime.set(0);}// 输出正常日志log.info("✅ 数据库正常 | 响应时间: {}ms", responseTime);}private void handleFailure() {// 增加失败计数int failures = consecutiveFailures.incrementAndGet();// 记录第一次失败时间if (failures == 1) {lastFailureTime.set(System.currentTimeMillis());}// 获取宕机时长(秒)long downTime = 0;if (lastFailureTime.get() > 0) {downTime = (System.currentTimeMillis() - lastFailureTime.get()) / 1000;}// 输出错误日志log.error("❌ 数据库连接失败 | 连续失败次数: {} | 宕机时长: {}秒", failures, downTime);}// 获取数据库状态(供其他服务查询)public boolean isDatabaseUp() {return consecutiveFailures.get() == 0;}// 获取数据库最后健康时间public long getLastHealthyTime() {return lastSuccessTime.get();}}

断开mysql连接,会自动尝试重连,并记录宕机时长

http://www.lqws.cn/news/445429.html

相关文章:

  • 191. 位1的个数
  • vs code配置go开发环境以及问题解决 could not import cannot find package in GOROOT or GOPATH
  • Linux树莓派项目实战:外网访问、PWM呼吸灯、超声波测距与驱动开发
  • Linux内核中通过perf_event监控内存访问的硬件断点触发流程
  • LINUX 619 NFS rsync
  • Neo4j操作指南:修改节点数据与新增节点属性
  • 1. C++ WebServer项目分享
  • Kafka性能调优全攻略:从JVM参数到系统优化
  • M-DPO复现
  • 从Excel到知识图谱再到数据分析:数据驱动智能体构建指南
  • HALCON相机标定
  • 安装MySQL 5.7导入数据,修改密码,创建账号并授权
  • CppCon 2017 学习:Everything You Ever Wanted to Know about DLLs
  • craw14ai 框架的入门讲解和实战指南——基于Python的智能爬虫框架,集成AI(如NLP/OCR)实现自动化数据采集与处理
  • 协作式机器人助力提高生产速度和效益
  • Molmo and PixMo论文精读
  • Java SE - String自定义类型
  • Docker 日志
  • XMOS基于边缘AI+DSP+MCU+I/O智算芯片的音频解决方案矩阵引领行业创新潮流
  • 运维人员常用网站列表
  • 【深度学习】条件随机场(CRF)深度解析:原理、应用与前沿
  • day35-Django(1)
  • MySQL 面试之事务和锁篇
  • 如何设计可维护、可扩展的测试框架
  • 软件范式正在经历第三次革命
  • 全网独家源码出售,电商任务系统补单平台系统源码部署搭建全开源支持二次开发
  • ubuntu 系统 pgm图片和png相互转化
  • Haproxy搭建web集群
  • 泛微OAe9-后端二开常见数据库操作
  • C++实现手写strlen函数