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.pswp.cn/web/84179.shtml
繁體地址,請注明出處:http://hk.pswp.cn/web/84179.shtml
英文地址,請注明出處:http://en.pswp.cn/web/84179.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

Qt聯合Halcon開發一:Qt配置Halcon環境【詳細圖解流程】

在Qt中使用Halcon庫進行圖像處理開發&#xff0c;可以有效地結合Qt的圖形界面和Halcon強大的計算機視覺功能。下面是詳細的配置過程&#xff0c;幫助你在Qt項目中成功集成Halcon庫。 步驟 1: 安裝Halcon軟件并授權 首先&#xff0c;確保你已經在電腦上安裝了Halcon軟件&#x…

一體化(HIS系統)醫院信息系統,讓醫療數據互聯互通

在醫療信息化浪潮下&#xff0c;HIS系統、LIS系統、PACS系統、電子病歷系統等信息系統成為醫療機構必不可少的一部分&#xff0c;從患者掛號到看診&#xff0c;從各種檢查到用藥&#xff0c;從院內治療到院外管理……醫療機構不同部門、不同科室的各類醫療、管理業務幾乎都初步…

Spring Boot 的 3 種二級緩存落地方式

在高并發系統設計中&#xff0c;緩存是提升性能的關鍵策略之一。隨著業務的發展&#xff0c;單一的緩存方案往往無法同時兼顧性能、可靠性和一致性等多方面需求。 此時&#xff0c;二級緩存架構應運而生&#xff0c;本文將介紹在Spring Boot中實現二級緩存的三種方案。 一、二…

Android Studio Profiler使用

一:memory 參考文獻: AndroidStudio之內層泄漏工具Profiler使用指南_android studio profiler-CSDN博客

Zephyr boot

<!DOCTYPE html> <html lang"zh-CN"> <head> <meta charset"UTF-8"> <meta name"viewport" content"widthdevice-width, initial-scale1.0"> <title>Zephyr設備初始化機制交互式解析…

騰訊地圖Web版解決熱力圖被輪廓覆蓋的問題

前言 你好&#xff0c;我是喵喵俠。 還記得那天傍晚&#xff0c;我正對著電腦調試一個騰訊地圖的熱力圖頁面。項目是一個區域人流密度可視化模塊&#xff0c;我加了一個淡藍色的輪廓圖層用于表示區域范圍&#xff0c;熱力圖放在下面用于展示人流熱度。效果一預覽&#xff0c;…

【JVMGC垃圾回收場景總結】

文章目錄 CMS在并發標記階段&#xff0c;已經被標記的對象&#xff0c;又被新生代跨帶引用&#xff0c;這時JVM會怎么處理?為什么 Minor GC 會發生 STW&#xff1f;有哪些對象是在棧上分配的&#xff1f;對象在 JVM 中的內存結構為什么需要對齊填充&#xff1f;JVM 對象分配空…

3_STM32開發板使用(STM32F103ZET6)

STM32開發板使用(STM32F103ZET6) 一、概述 當前所用開發板為正點原子精英板,MCU: STM32F103ZET6。一般而言,拿到板子之后先要對板子有基礎的認識,包括對開發板上電開機、固件下載、調試方法這三個部分有基本的掌握。 二、系統開機 2.1 硬件連接 直接接電源線或Type-c線…

crackme012

crackme012 名稱值軟件名稱attackiko.exe加殼方式無保護方式serial編譯語言Delphi v1.0調試環境win10 64位使用工具x32dbg,PEid破解日期2025-06-18 -發現是 16位windows 程序環境還沒搭好先留坑

CppCon 2016 學習:I Just Wanted a Random Integer

你想要一個隨機整數&#xff0c;用于模擬隨機大小的DNA讀取片段&#xff08;reads&#xff09;&#xff0c;希望覆蓋不同長度范圍&#xff0c;也能測試邊界情況。 代碼部分是&#xff1a; #include <cstdlib> auto r std::rand() % 100;它生成一個0到99之間的隨機整數&…

MySQL層級查詢實戰:無函數實現部門父路徑

本次需要擊斃的MySQL函數 函數主要用于獲取部門的完整層級路徑&#xff0c;方便在應用程序或SQL查詢中直接調用&#xff0c;快速獲得部門的上下級關系信息。執行該函數之后簡單使用SQL可以實現數據庫中部門名稱查詢。例如下面sql select name,GetDepartmentParentNames(du.de…

Python初學者教程:如何從文本中提取IP地址

Python初學者教程:如何從文本中提取IP地址 在網絡安全和數據分析領域,經常需要從文本文件中提取IP地址。本文將引導您使用Python創建一個簡單但實用的工具,用于從文本文件提取所有IP地址并將其保存到新文件中。即使您是編程新手,也可以跟隨本教程學習Python的基礎知識! …

【Redis】Redis核心探秘:數據類型的編碼實現與高速訪問之道

&#x1f4da;?前言 &#x1f31f;&#x1f31f;&#x1f31f;精彩導讀 本次我們將全面剖析Redis的核心技術要點&#xff0c;包括其豐富的數據類型體系、高效的編碼方式以及秒級響應的性能奧秘。對于渴望深入理解Redis底層機制的技術愛好者&#xff0c;這是一次難得的學習機會…

Halcon —— 多種二維碼檢測

工業視覺實戰&#xff1a;Halcon多類型二維碼識別技術詳解 在工業自動化場景中&#xff0c;兼容多種二維碼類型是提高生產線靈活性的關鍵。本文將深入解析Halcon實現Data Matrix、QR Code和PDF417三種主流二維碼的兼容識別方案&#xff0c;并重點解釋核心算子參數。 一、多類型…

安卓vscodeAI開發實例

前言 前些天發現了一個巨牛的人工智能免費學習網站&#xff0c;通俗易懂&#xff0c;風趣幽默&#xff0c;忍不住分享一下給大家。點擊跳轉到網站 目錄 一、安卓開發基礎與工具鏈革新 1.1 Android Studio的局限性分析 1.2 VSCode在移動開發中的崛起 1.3 跨平臺開發工具鏈對比…

③通用搜索---解析FastAdmin中的表格列表的功能

深度解析FastAdmin中的表格列表的功能-CSDN博客文章瀏覽閱讀25次。本文將FastAdmin框架的CRUD功能配置要點進行了系統梳理。官方文檔與開發經驗相結合&#xff0c;詳細介紹了菜單顯示、TAB過濾、通用搜索、工具欄按鈕、動態統計、快速搜索等17項功能的配置方法。包括字段渲染&a…

DeepSeek 助力 Vue3 開發:打造絲滑的日歷(Calendar),日歷_項目里程碑示例(CalendarView01_22)

前言&#xff1a;哈嘍&#xff0c;大家好&#xff0c;今天給大家分享一篇文章&#xff01;并提供具體代碼幫助大家深入理解&#xff0c;徹底掌握&#xff01;創作不易&#xff0c;如果能幫助到大家或者給大家一些靈感和啟發&#xff0c;歡迎收藏關注哦 &#x1f495; 目錄 Deep…

Python爬蟲實戰:獲取Diesel電商數據并分析

1. 引言 在當今數字化時代,電商平臺積累了海量的產品和用戶數據。通過對這些數據的挖掘和分析,企業可以深入了解市場動態、消費者需求和競爭態勢,從而制定更有效的營銷策略和產品規劃。Diesel 作為知名的時尚品牌,其在電商平臺上的表現備受關注。本研究旨在通過 Python 爬…

Spring RestTemplate + MultiValueMap vs OkHttp 多值參數的處理

&#x1f4cc; Spring RestTemplate vs OkHttp&#xff1a;多值參數處理 一、MultiValueMap 與 FormBody 的差異 特性RestTemplate MultiValueMapOkHttp FormBody多值參數支持? 原生支持&#xff08;add("key", "value") 自動追加&#xff09;? 需顯…

GelSight視觸覺3D輪廓儀賦能Beomni人形機器人觸覺遙測,開啟人形機器人觸覺應用新場景

在智能制造、航空航天等領域&#xff0c;傳統機器人常面臨操作精度不足、環境適應力弱等問題。GelSight觸覺傳感技術與Beomni人形機器人的融合&#xff0c;為這些場景提供了新可能 —— 通過亞微米級觸覺感知能力&#xff0c;操作員可遠程感知物體表面細節&#xff0c;在復雜環…