diff --git a/jeecg-boot-base-core/src/main/java/org/jeecg/common/constant/DBSQL.java b/jeecg-boot-base-core/src/main/java/org/jeecg/common/constant/DBSQL.java index e39a2b8d..48bf4457 100644 --- a/jeecg-boot-base-core/src/main/java/org/jeecg/common/constant/DBSQL.java +++ b/jeecg-boot-base-core/src/main/java/org/jeecg/common/constant/DBSQL.java @@ -12,6 +12,13 @@ public interface DBSQL { "0.0 AS used, 0.0 AS dataSize, 0.0 AS indexSize " + "FROM pg_class WHERE relkind = 'r' AND relname NOT LIKE 'pg_%' AND relname NOT LIKE 'sql_%'"; + String DBSTATUS_PG = "SELECT *, 0 AS logResidue FROM " + + "(SELECT COUNT(*) AS loginNum FROM pg_stat_activity WHERE query_start >= now() - interval '1 minute') AS loginNum," + + "(SELECT COUNT(*) AS connNum FROM pg_stat_activity WHERE query_start >= now() - interval '1 minute') AS connNum," + + "(SELECT ROUND(SUM(pg_database_size(datname)) / 1024 / 1024, 0) AS dataSize FROM pg_database) AS dataSize"; + + String DBSTATUS_CONN_PG = "SELECT COUNT(*) FROM pg_stat_activity WHERE query_start >= now() - interval '1 minute'"; + /* Oracle */ String DBNAMES_OR = "SELECT username FROM all_users"; String DBINFO_OR = "SELECT a.table_name AS tableName, a.num_rows AS numRow," + @@ -39,6 +46,14 @@ public interface DBSQL { "AND d.segment_type = 'INDEX' WHERE a.owner = '%s' " + "ORDER BY a.table_name"; + String DBSTATUS_OR = "SELECT * FROM " + + "(SELECT COUNT(*) AS loginNum FROM V$SESSION WHERE LOGON_TIME >= SYSDATE - 1 / 24 / 60 AND TYPE = 'USER')," + + "(SELECT COUNT(*) AS connNum FROM V$SESSION WHERE LOGON_TIME >= SYSDATE - 1 / 24 / 60)," + + "(SELECT SUM(BYTES) / 1024 / 1024 AS logResidue FROM V$log WHERE ARCHIVED = 'NO')," + + "(SELECT SUM(BYTES) / 1024 / 1024 AS dataSize FROM dba_data_files)"; + + String DBSTATUS_CONN_OR = "SELECT COUNT(*) FROM V$SESSION WHERE LOGON_TIME >= SYSDATE - 1 / 24 / 60"; + /* MySQL */ String DBNAMES_MY = "SHOW DATABASES"; String DBINFO_MY = "SELECT TABLE_NAME AS tableName, TABLE_ROWS AS numRow," + diff --git a/jeecg-boot-base-core/src/main/java/org/jeecg/modules/base/dto/DatabaseStatusConn.java b/jeecg-boot-base-core/src/main/java/org/jeecg/modules/base/dto/DatabaseStatusConn.java new file mode 100644 index 00000000..1cc6c29b --- /dev/null +++ b/jeecg-boot-base-core/src/main/java/org/jeecg/modules/base/dto/DatabaseStatusConn.java @@ -0,0 +1,28 @@ +package org.jeecg.modules.base.dto; + +import com.baomidou.mybatisplus.annotation.TableName; +import lombok.Data; +import org.jeecg.common.system.base.entity.JeecgEntity; + +import java.time.LocalDateTime; + +@Data +@TableName("database_status_conn") +public class DatabaseStatusConn extends JeecgEntity { + + // private Double memory; + // + // private Integer loginNum; + + private Integer connNum; + + // private Double respTime; // 单位: 秒(S) + // + // private Double logResidue; // 单位 MB + // + // private Double dataSize; // 单位 MB + + private String databaseId; + + private LocalDateTime collectTime; +} diff --git a/jeecg-module-abnormal-alarm/src/main/java/org/jeecg/modules/DatabaseStatusFetcher.java b/jeecg-module-abnormal-alarm/src/main/java/org/jeecg/modules/DatabaseStatusFetcher.java new file mode 100644 index 00000000..3dd5e632 --- /dev/null +++ b/jeecg-module-abnormal-alarm/src/main/java/org/jeecg/modules/DatabaseStatusFetcher.java @@ -0,0 +1,38 @@ +package org.jeecg.modules; + +import org.jeecg.common.constant.DBSQL; +import org.jeecg.common.util.JDBCUtil; +import org.jeecg.modules.base.entity.postgre.SysDatabase; +import org.jeecg.modules.databaseStatus.ConnFetcher; +import org.jeecg.modules.service.ISysDatabaseService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.jdbc.core.JdbcTemplate; +import org.springframework.stereotype.Component; + +import java.util.List; + +@Component +public class DatabaseStatusFetcher { + + @Autowired + private ISysDatabaseService databaseService; + + public void start(){ + List databases = databaseService.list(); + // 采集数据库连接数 + Thread connFetcher = new Thread(new ConnFetcher(databases)); + connFetcher.setName("Thread-connFetcher"); + connFetcher.start(); + // ... + } + + public static void main(String[] args) { + String url = "jdbc:oracle:thin:@82.157.234.81:1521:XE"; + String driver = "oracle.jdbc.OracleDriver"; + String user = "configuration"; + String pass = "123456"; + + JdbcTemplate template = JDBCUtil.template(url, driver, user, pass); + System.out.println(template.queryForObject(DBSQL.DBSTATUS_CONN_OR, Integer.class)); + } +} diff --git a/jeecg-module-abnormal-alarm/src/main/java/org/jeecg/modules/controller/SysDatabaseStatusController.java b/jeecg-module-abnormal-alarm/src/main/java/org/jeecg/modules/controller/SysDatabaseStatusController.java new file mode 100644 index 00000000..8388153c --- /dev/null +++ b/jeecg-module-abnormal-alarm/src/main/java/org/jeecg/modules/controller/SysDatabaseStatusController.java @@ -0,0 +1,17 @@ +package org.jeecg.modules.controller; + +import io.swagger.annotations.Api; +import org.jeecg.modules.service.IDatabaseStatusConnService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.*; + +@RestController +@RequestMapping("sysDatabaseStatus") +@Api(value = "数据库状态信息管理", tags = "数据库状态信息管理") +public class SysDatabaseStatusController { + + @Autowired + private IDatabaseStatusConnService databaseStatusService; + + +} diff --git a/jeecg-module-abnormal-alarm/src/main/java/org/jeecg/modules/databaseStatus/ConnFetcher.java b/jeecg-module-abnormal-alarm/src/main/java/org/jeecg/modules/databaseStatus/ConnFetcher.java new file mode 100644 index 00000000..3c396c61 --- /dev/null +++ b/jeecg-module-abnormal-alarm/src/main/java/org/jeecg/modules/databaseStatus/ConnFetcher.java @@ -0,0 +1,101 @@ +package org.jeecg.modules.databaseStatus; + +import cn.hutool.core.collection.CollUtil; +import cn.hutool.core.util.ObjectUtil; +import lombok.extern.slf4j.Slf4j; +import org.jeecg.common.constant.DBSQL; +import org.jeecg.common.constant.enums.DbType; +import org.jeecg.common.util.JDBCUtil; +import org.jeecg.common.util.SpringContextUtils; +import org.jeecg.modules.base.dto.DatabaseStatusConn; +import org.jeecg.modules.base.entity.postgre.SysDatabase; +import org.jeecg.modules.service.IDatabaseStatusConnService; +import org.springframework.jdbc.core.JdbcTemplate; +import org.springframework.jdbc.core.RowMapper; + +import java.time.LocalDateTime; +import java.util.ArrayList; +import java.util.Iterator; +import java.util.List; + +import static org.jeecg.common.constant.enums.DbType.typeOf; + +/* +* 收集数据源的连接数信息 入库 +* */ +@Slf4j +public class ConnFetcher implements Runnable{ + + private List databases; + + private IDatabaseStatusConnService connService; + + public ConnFetcher(List databases) { + this.databases = databases; + connService = SpringContextUtils.getBean(IDatabaseStatusConnService.class); + } + + @Override + public void run() { + if (CollUtil.isEmpty(databases)) return; + List statusList = new ArrayList<>(); + Iterator iterator = databases.iterator(); + while (true){ + LocalDateTime now = LocalDateTime.now(); + while (iterator.hasNext()) { + try { + SysDatabase database= iterator.next(); + String databaseId = database.getId(); + String dbType = database.getDbType(); + String dbUrl = database.getDbUrl(); + String dbDriver = database.getDbDriver(); + String dbUsername = database.getDbUsername(); + String dbPassword = database.getDbPassword(); + JdbcTemplate template = JDBCUtil.template(dbUrl, dbDriver, dbUsername, dbPassword); + if (ObjectUtil.isNull(template)) { + iterator.remove(); + continue; + } + Integer conn = null; + // 根据数据库类型选择执行哪种数据库的状态查询SQL + DbType dbTypeE = typeOf(dbType); + if (ObjectUtil.isNotNull(dbTypeE)){ + switch (dbTypeE){ + case POSTGRESQL: + conn = template.queryForObject(DBSQL.DBSTATUS_CONN_PG, Integer.class); + break; + case ORACLE: + conn = template.queryForObject(DBSQL.DBSTATUS_CONN_OR, Integer.class); + break; + case MYSQL55: + // ... + break; + case MYSQL57: + // ... + break; + default: + break; + } + } + // 如果conn == null 说明数据源类型不确定 + if (ObjectUtil.isNull(conn)) { + iterator.remove(); + continue; + } + DatabaseStatusConn databaseStatus = new DatabaseStatusConn(); + databaseStatus.setConnNum(conn); + databaseStatus.setDatabaseId(databaseId); + databaseStatus.setCollectTime(now); + // 数据达到一定数量,进行批量保存 + statusList.add(databaseStatus); + if (statusList.size() == 5){ + connService.saveBatch(statusList); + statusList = new ArrayList<>(); + } + }catch (Exception e){ + log.error("ConnFetcher采集数据库连接数异常: {}", e.getMessage()); + } + } + } + } +} diff --git a/jeecg-module-abnormal-alarm/src/main/java/org/jeecg/modules/databaseStatus/StatusFetcher.java b/jeecg-module-abnormal-alarm/src/main/java/org/jeecg/modules/databaseStatus/StatusFetcher.java new file mode 100644 index 00000000..8fdabcd4 --- /dev/null +++ b/jeecg-module-abnormal-alarm/src/main/java/org/jeecg/modules/databaseStatus/StatusFetcher.java @@ -0,0 +1,104 @@ +package org.jeecg.modules.databaseStatus; + +import cn.hutool.core.util.ObjectUtil; +import lombok.extern.slf4j.Slf4j; +import org.jeecg.common.constant.DBSQL; +import org.jeecg.common.constant.enums.DbType; +import org.jeecg.common.util.JDBCUtil; +import org.jeecg.common.util.SpringContextUtils; +import org.jeecg.modules.base.dto.DatabaseStatusConn; +import org.jeecg.modules.base.entity.postgre.SysDatabase; +import org.jeecg.modules.service.IDatabaseStatusConnService; +import org.springframework.jdbc.core.JdbcTemplate; +import org.springframework.jdbc.core.RowMapper; + +import java.math.BigDecimal; +import java.math.RoundingMode; +import java.util.ArrayList; +import java.util.List; +import java.util.concurrent.TimeUnit; + +import static org.jeecg.common.constant.enums.DbType.typeOf; + +/* +* 收集数据源的状态信息 入库 +* */ +@Slf4j +public class StatusFetcher implements Runnable{ + + private final long sleepTime = 30 * 60 * 1000; + + private final SysDatabase database; + + private IDatabaseStatusConnService statusService; + + public StatusFetcher(SysDatabase database) { + this.database = database; + statusService = SpringContextUtils.getBean(IDatabaseStatusConnService.class); + } + + @Override + public void run() { + if (ObjectUtil.isNull(database)) return; + String databaseId = database.getId(); + String dbType = database.getDbType(); + String dbUrl = database.getDbUrl(); + String dbDriver = database.getDbDriver(); + String dbUsername = database.getDbUsername(); + String dbPassword = database.getDbPassword(); + List statusList = new ArrayList<>(); + while (true){ + try { + long start = System.currentTimeMillis(); + JdbcTemplate template = JDBCUtil.template(dbUrl, dbDriver, dbUsername, dbPassword); + long end = System.currentTimeMillis(); + + /* + 如果template == null 表示数据源连接失败,睡眠30min后重试 + 如果template != null 则表示连接成功,同时记录数据源连接响应时间 + */ + if (ObjectUtil.isNull(template)){ + TimeUnit.MILLISECONDS.sleep(sleepTime); + log.warn("数据源"); + continue; + } + log.info("11111111111111111111111111111111111111111111111"); + DatabaseStatusConn databaseStatus = null; + // 根据数据库类型选择执行哪种数据库的状态查询SQL + DbType dbTypeE = typeOf(dbType); + if (ObjectUtil.isNotNull(dbTypeE)){ + switch (dbTypeE){ + case POSTGRESQL: + // databaseStatus = template.queryForObject(DBSQL.DBSTATUS_PG, mapper); + break; + case ORACLE: + // databaseStatus = template.queryForObject(DBSQL.DBSTATUS_OR, mapper); + break; + case MYSQL55: + // ... + break; + case MYSQL57: + // ... + break; + default: + break; + } + } + // 如果databaseStatus == null 说明数据源类型不确定 + if (ObjectUtil.isNull(databaseStatus)) return; + databaseStatus.setDatabaseId(databaseId); + // 设置数据的响应时间 + BigDecimal decimal = new BigDecimal((end - start)); + double respTime = decimal.divide(new BigDecimal(1000), 2, RoundingMode.HALF_UP).doubleValue(); + //databaseStatus.setRespTime(respTime); + // 数据达到一定数量,进行批量保存 + statusList.add(databaseStatus); + if (statusList.size() == 300){ + statusService.saveBatch(statusList); + } + }catch (Exception e){ + + } + } + } +} diff --git a/jeecg-module-abnormal-alarm/src/main/java/org/jeecg/modules/mapper/DatabaseStatusConnMapper.java b/jeecg-module-abnormal-alarm/src/main/java/org/jeecg/modules/mapper/DatabaseStatusConnMapper.java new file mode 100644 index 00000000..d6befb28 --- /dev/null +++ b/jeecg-module-abnormal-alarm/src/main/java/org/jeecg/modules/mapper/DatabaseStatusConnMapper.java @@ -0,0 +1,8 @@ +package org.jeecg.modules.mapper; + +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import org.jeecg.modules.base.dto.DatabaseStatusConn; + +public interface DatabaseStatusConnMapper extends BaseMapper { + +} diff --git a/jeecg-module-abnormal-alarm/src/main/java/org/jeecg/modules/mapper/xml/DatabaseStatusConnMapper.xml b/jeecg-module-abnormal-alarm/src/main/java/org/jeecg/modules/mapper/xml/DatabaseStatusConnMapper.xml new file mode 100644 index 00000000..308fdffa --- /dev/null +++ b/jeecg-module-abnormal-alarm/src/main/java/org/jeecg/modules/mapper/xml/DatabaseStatusConnMapper.xml @@ -0,0 +1,5 @@ + + + + + \ No newline at end of file diff --git a/jeecg-module-abnormal-alarm/src/main/java/org/jeecg/modules/service/IDatabaseStatusConnService.java b/jeecg-module-abnormal-alarm/src/main/java/org/jeecg/modules/service/IDatabaseStatusConnService.java new file mode 100644 index 00000000..5b4f00a4 --- /dev/null +++ b/jeecg-module-abnormal-alarm/src/main/java/org/jeecg/modules/service/IDatabaseStatusConnService.java @@ -0,0 +1,9 @@ +package org.jeecg.modules.service; + +import com.baomidou.mybatisplus.extension.service.IService; +import org.jeecg.modules.base.dto.DatabaseStatusConn; + +public interface IDatabaseStatusConnService extends IService { + + +} diff --git a/jeecg-module-abnormal-alarm/src/main/java/org/jeecg/modules/service/impl/DatabaseStatusConnServiceImpl.java b/jeecg-module-abnormal-alarm/src/main/java/org/jeecg/modules/service/impl/DatabaseStatusConnServiceImpl.java new file mode 100644 index 00000000..42048ffd --- /dev/null +++ b/jeecg-module-abnormal-alarm/src/main/java/org/jeecg/modules/service/impl/DatabaseStatusConnServiceImpl.java @@ -0,0 +1,12 @@ +package org.jeecg.modules.service.impl; + +import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; +import org.jeecg.modules.base.dto.*; +import org.jeecg.modules.mapper.DatabaseStatusConnMapper; +import org.jeecg.modules.service.IDatabaseStatusConnService; +import org.springframework.stereotype.Service; + +@Service("databaseStatusConnService") +public class DatabaseStatusConnServiceImpl extends ServiceImpl implements IDatabaseStatusConnService { + +} diff --git a/jeecg-server-cloud/armd-abnormal-alarm-start/src/main/java/org/jeecg/JeecgAbnormalAlarmApplication.java b/jeecg-server-cloud/armd-abnormal-alarm-start/src/main/java/org/jeecg/JeecgAbnormalAlarmApplication.java index c4d82d26..e1763c58 100644 --- a/jeecg-server-cloud/armd-abnormal-alarm-start/src/main/java/org/jeecg/JeecgAbnormalAlarmApplication.java +++ b/jeecg-server-cloud/armd-abnormal-alarm-start/src/main/java/org/jeecg/JeecgAbnormalAlarmApplication.java @@ -3,6 +3,7 @@ package org.jeecg; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; import org.jeecg.common.util.oConvertUtils; +import org.jeecg.modules.DatabaseStatusFetcher; import org.jeecg.modules.DatabaseStatusManager; import org.jeecg.modules.EmailStatusManager; import org.jeecg.modules.ServerStatusManager; @@ -32,6 +33,8 @@ public class JeecgAbnormalAlarmApplication extends SpringBootServletInitializer private final DatabaseStatusManager databaseStatusManager; + private final DatabaseStatusFetcher databaseStatusFetcher; + @Override protected SpringApplicationBuilder configure(SpringApplicationBuilder application) { return application.sources(JeecgAbnormalAlarmApplication.class); @@ -59,6 +62,8 @@ public class JeecgAbnormalAlarmApplication extends SpringBootServletInitializer emailStatusManager.start(); // 启动监测服务器连接状态的线程 serverStatusManager.start(); + // 启动采集数据库状态信息线程组 + databaseStatusFetcher.start(); } } \ No newline at end of file diff --git a/jeecg-server-cloud/armd-spectrum-analysis-start/src/main/resources/application.yml b/jeecg-server-cloud/armd-spectrum-analysis-start/src/main/resources/application.yml index 3deaf293..79f51140 100644 --- a/jeecg-server-cloud/armd-spectrum-analysis-start/src/main/resources/application.yml +++ b/jeecg-server-cloud/armd-spectrum-analysis-start/src/main/resources/application.yml @@ -15,5 +15,5 @@ spring: config: import: - optional:nacos:armd.yaml - - optional:nacos:armd-@profile.name@.yaml + - optional:nacos:armd-@profile.name@1.yaml - optional:nacos:armd-analysis-@profile.name@.yaml