Sfoglia il codice sorgente

江津/自来水 优化小时原始数据获取,并且增添重试机制

1037015548@qq.com 2 mesi fa
parent
commit
556ea5e303

+ 6 - 4
src/main/java/com/shkpr/service/aimodelpower/bizmgr/KprAimTapWaterBizFun.java

@@ -59,7 +59,7 @@ public class KprAimTapWaterBizFun {
                             //TODO 根据当前配置信息item 查询远通数据中的历史数据
                             //TODO 首先查询当前水厂设备的从昨天之后到得到数据的数据
                             LocalDateTime today = LocalDateTime.now();
-                            LocalDateTime startDateTime = today.withHour(0).withMinute(0).withSecond(0).withNano(0).minusHours(1);
+                            LocalDateTime startDateTime = today.withMinute(0).withSecond(0).withNano(0).minusHours(6);
 
                             //TODO 需计算的循环天数
 
@@ -291,6 +291,7 @@ public class KprAimTapWaterBizFun {
                 System.out.println("比对远通原始数据开始时间:"+TimeTool.convertUTC2DateStr(TimeTool.getCurMsUTC(),TimeTool.TIMESTAMP_FORMAT));
                 System.out.println("进行中:......");
                 final CountDownLatch latch = new CountDownLatch(configList.size());
+                LocalDateTime startTimeLocal = LocalDateTime.now().minusDays(1).minusHours(1);
                 for(Map<String,Object> item:configList){
                     try{
                         ThreadTaskMgr.runTask(new TraceRunnable(TraceLogMgr.getTraceId()) {
@@ -298,7 +299,7 @@ public class KprAimTapWaterBizFun {
                             public void function() {
                                 //TODO 根据当前配置信息item 查询远通数据中的历史数据
                                 //TODO 首先查询当前水厂设备的2025-01-01之后到最新数据的数据总数,然后分页形式获取数据
-                                Integer itemCount = getWaterTapWaterApi().getTabWaterHistoryCount(" WHERE TAG_CODE = '"+item.get("collcation_tag")+"' and QCQUISITION_TIME >= to_date('2025-01-01 00:00:00', 'yyyy-mm-dd hh24:mi:ss')");
+                                Integer itemCount = getWaterTapWaterApi().getTabWaterHistoryCount(" WHERE TAG_CODE = '"+item.get("collcation_tag")+"' and QCQUISITION_TIME >= to_date('"+startTimeLocal.format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"))+"', 'yyyy-mm-dd hh24:mi:ss')");
                                 if(itemCount!=null&&itemCount>0) {
                                     //TODO 优化 以分页方式查询所有,初始分页行数定为2000查询速率较好
                                     int pageNum = itemCount%2000==0?itemCount/2000:(itemCount/2000)+1;//总页数
@@ -316,7 +317,7 @@ public class KprAimTapWaterBizFun {
                                         }else{
                                             limitNew = 2000;
                                         }
-                                        List<Map<String,Object>> tapWaterHistoryList = getWaterTapWaterApi().getPageZILAISHUI_HISTORY2(limitNew,offset," AND TAG_CODE = '"+item.get("collcation_tag")+"' and QCQUISITION_TIME >= to_date('2025-01-01 00:00:00', 'yyyy-mm-dd hh24:mi:ss')");
+                                        List<Map<String,Object>> tapWaterHistoryList = getWaterTapWaterApi().getPageZILAISHUI_HISTORY2(limitNew,offset," AND TAG_CODE = '"+item.get("collcation_tag")+"' and QCQUISITION_TIME >= to_date('"+startTimeLocal.format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"))+"', 'yyyy-mm-dd hh24:mi:ss')");
                                         if(!CollectionUtils.isEmpty(tapWaterHistoryList)){
                                             //TODO 循环远通水量数据列表,查询数据不存在的话就插入
                                             for (int j = 0; j < tapWaterHistoryList.size(); j++) {
@@ -390,7 +391,8 @@ public class KprAimTapWaterBizFun {
                             public void function() {
                                 //TODO 根据当前配置信息item 查询远通数据中的历史数据
                                 //TODO 首先查询当前水厂设备的从2025-01-01之后到得到数据
-                                LocalDateTime startDateTime = LocalDateTime.of(2025, 01, 01, 00, 00, 00);
+                                LocalDateTime startDateTime = LocalDateTime.now().withMinute(0).withSecond(0)
+                                        .minusDays(1).minusHours(1);
 
                                 //TODO 需计算的循环天数
                                 Long days = 0L;

+ 22 - 1
src/main/java/com/shkpr/service/aimodelpower/configuration/OrcaleDataSourceConfig.java

@@ -30,7 +30,28 @@ public class OrcaleDataSourceConfig {
         config.setUsername(username);
         config.setPassword(password);
         config.setDriverClassName(driverClassName);
-        config.setInitializationFailTimeout(-1);
+
+        // Oracle专用优化参数
+        config.setConnectionTestQuery("SELECT 1 FROM DUAL");  // Oracle心跳检测SQL
+        config.setConnectionTimeout(30000);  // 连接获取超时时间(毫秒)
+        config.setValidationTimeout(5000);   // 连接验证超时时间(毫秒)
+
+        // 连接池大小设置(根据Oracle服务器性能调整)
+        config.setMaximumPoolSize(20);       // 最大连接数(默认10)
+        config.setMinimumIdle(5);            // 最小空闲连接数
+
+        // 连接生命周期控制
+        config.setIdleTimeout(600000);       // 空闲连接超时(10分钟)
+        config.setMaxLifetime(1800000);      // 连接最大存活时间(30分钟)
+
+        // Oracle推荐关闭自动提交(根据业务需求)
+//        config.setAutoCommit(false);         // 建议手动控制事务
+
+        // 连接泄露检测(生产环境建议开启)
+        config.setLeakDetectionThreshold(60000); // 60秒未关闭则报泄露
+
+        // 初始化失败超时(避免无限等待)
+        config.setInitializationFailTimeout(60000); // 60秒超时
         return new HikariDataSource(config);
     }
 

+ 65 - 32
src/main/java/com/shkpr/service/aimodelpower/dbdao/shizilaishuiDataSource/WaterZILAISHUIDao.java

@@ -4,6 +4,7 @@ import com.shkpr.service.aimodelpower.bizmgr.KprAimWaterCollecationBizFun;
 import lombok.extern.slf4j.Slf4j;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.beans.factory.annotation.Qualifier;
+import org.springframework.dao.DataAccessException;
 import org.springframework.jdbc.core.JdbcTemplate;
 import org.springframework.stereotype.Repository;
 import org.springframework.util.ObjectUtils;
@@ -35,46 +36,78 @@ public class WaterZILAISHUIDao {
     //TODO orcale相关
     //TODO 获取满足条件的历史水量数据总数
     public Integer getTabWaterHistoryCount(String extend){
-        try {
-            String sql = "select count(1)  from cqda.V_SHIZILAISHUI_HISTORY2 ";
-            if("water_volume_prediction_jiangjin2".equals(KprAimWaterCollecationBizFun.databaseName)){
-                sql = "select count(1)  from cqda.V_JIANGJIN_HISTORY";
-            }
-            if(!StringUtils.isEmpty(extend)){
-                sql += extend;
+        int maxAttempts = 10; // 最大重试次数
+        int attempt = 0;
+        long delay = 1000; // 初始延迟时间(毫秒)
+        while (attempt < maxAttempts) {
+            try {
+                String sql = "select count(1)  from cqda.V_SHIZILAISHUI_HISTORY2 ";
+                if ("water_volume_prediction_jiangjin2".equals(KprAimWaterCollecationBizFun.databaseName)) {
+                    sql = "select count(1)  from cqda.V_JIANGJIN_HISTORY";
+                }
+                if (!StringUtils.isEmpty(extend)) {
+                    sql += extend;
+                }
+                int count = oneTemplate.queryForObject(sql, Integer.class);
+                return count;
+            } catch (Exception ex) {
+                // 捕获连接获取失败异常
+                attempt++;
+                if (attempt >= maxAttempts) {
+                    return null;
+                }
+                try {
+                    Thread.sleep(delay); // 延迟重试
+                } catch (InterruptedException e) {
+                    Thread.currentThread().interrupt();
+                }
+                delay *= 2; // 指数退避策略
             }
-            int count = oneTemplate.queryForObject(sql, Integer.class);
-            return count;
-        }catch(Exception ex){
-            return null;
         }
+        return null;
     }
     //TODO 分页获取历史水量数据
     public List<Map<String,Object>> getPageZILAISHUI_HISTORY2(int limit,int offset,String extend){
-        try {
-            String tableName = "cqda.V_SHIZILAISHUI_HISTORY2";
-            String filedOrgName = "NAME";
-            if("water_volume_prediction_jiangjin2".equals(KprAimWaterCollecationBizFun.databaseName)){
-                tableName = "cqda.V_JIANGJIN_HISTORY ";
-                filedOrgName = "ORG_NAME";
-            }
-            String sql = "select " +
-                    " a.TAG_CODE,a."+filedOrgName+",a.VAL,TO_CHAR(a.QCQUISITION_TIME,'yyyy-mm-dd hh24:mi:ss') AS QCQUISITION_TIME," +
-                    " TO_CHAR(a.UPDATE_TIME,'yyyy-mm-dd hh24:mi:ss') AS UPDATE_TIME " +
-                    " from ( select t.*,rownum AS rownumber from "+tableName+"  t where rownum <= "+limit+") a " +
-                    " where rownumber > "+offset;
-            if (!StringUtils.isEmpty(extend)) {
-                sql = "select " +
-                        " a.TAG_CODE,a."+filedOrgName+",a.VAL,TO_CHAR(a.QCQUISITION_TIME,'yyyy-mm-dd hh24:mi:ss') AS QCQUISITION_TIME," +
+        int maxAttempts = 10; // 最大重试次数
+        int attempt = 0;
+        long delay = 1000; // 初始延迟时间(毫秒)
+        while (attempt < maxAttempts) {
+            try {
+                String tableName = "cqda.V_SHIZILAISHUI_HISTORY2";
+                String filedOrgName = "NAME";
+                if ("water_volume_prediction_jiangjin2".equals(KprAimWaterCollecationBizFun.databaseName)) {
+                    tableName = "cqda.V_JIANGJIN_HISTORY ";
+                    filedOrgName = "ORG_NAME";
+                }
+                String sql = "select " +
+                        " a.TAG_CODE,a." + filedOrgName + ",a.VAL,TO_CHAR(a.QCQUISITION_TIME,'yyyy-mm-dd hh24:mi:ss') AS QCQUISITION_TIME," +
                         " TO_CHAR(a.UPDATE_TIME,'yyyy-mm-dd hh24:mi:ss') AS UPDATE_TIME " +
-                        " from ( select t.*,rownum AS rownumber from "+tableName+"  t where rownum <= "+limit+" "+extend+") a " +
-                        " where rownumber >"+offset;
+                        " from ( select t.*,rownum AS rownumber from " + tableName + "  t where rownum <= " + limit + ") a " +
+                        " where rownumber > " + offset;
+                if (!StringUtils.isEmpty(extend)) {
+                    sql = "select " +
+                            " a.TAG_CODE,a." + filedOrgName + ",a.VAL,TO_CHAR(a.QCQUISITION_TIME,'yyyy-mm-dd hh24:mi:ss') AS QCQUISITION_TIME," +
+                            " TO_CHAR(a.UPDATE_TIME,'yyyy-mm-dd hh24:mi:ss') AS UPDATE_TIME " +
+                            " from ( select t.*,rownum AS rownumber from " + tableName + "  t where rownum <= " + limit + " " + extend + ") a " +
+                            " where rownumber >" + offset;
+                }
+                List<Map<String, Object>> tableData = oneTemplate.queryForList(sql);
+                return tableData;
+            } catch (Exception ex) {
+                // 捕获连接获取失败异常
+                attempt++;
+                if (attempt >= maxAttempts) {
+                    return null;
+                }
+                try {
+                    Thread.sleep(delay); // 延迟重试
+                } catch (InterruptedException e) {
+                    Thread.currentThread().interrupt();
+                }
+                delay *= 2; // 指数退避策略
             }
-            List<Map<String, Object>> tableData = oneTemplate.queryForList(sql);
-            return tableData;
-        }catch(Exception ex){
-            return null;
         }
+        return null;
     }
 
     //TODO pgsql water_volume_prediction数据库相关

+ 37 - 72
src/main/java/com/shkpr/service/aimodelpower/globalmgr/ScheduleTaskMgr.java

@@ -110,7 +110,7 @@ public class ScheduleTaskMgr {
     }
 
     //TODO 每天整点的十分执行检查小时用水量是否对齐,检查时间范围为当前时间到昨天
-    @Scheduled(cron = "0 10 * * * *")
+    @Scheduled(cron = "0 10 0 * * ?")
     public void executeTaskEveryHourAtTenMinutesRecord() {
         KprAimTapWaterBizFun.checkRecordData();
     }
@@ -169,7 +169,8 @@ public class ScheduleTaskMgr {
 //            @Override
 //            public void run() {
 //                String time = LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyy-MM"));
-//
+//                KprAimTapWaterBizFun.checkRecordAllData();
+//                KprAimTapWaterBizFun.initWaterCollecationReacordAll();
 //            }
 //        };
 //        timer2.schedule(timerTask1, 10000);
@@ -201,7 +202,7 @@ public class ScheduleTaskMgr {
     }
 
     @PostConstruct
-    public void initWaterRecordAll(){
+    public void initWaterRecordAllAndYuceWork(){
         Timer timer = new Timer();
         TimerTask timerTask1 = new TimerTask() {
             @Override
@@ -216,51 +217,15 @@ public class ScheduleTaskMgr {
             @Override
             public void run() {
                 KprAimTapWaterBizFun.checkRecordAllData();
-            }
-        };
-        timer2.schedule(timerTask2,11000);//11秒后执行一次
-    }
-
-    @PostConstruct
-    public void initWaterDay(){
-        Timer timer = new Timer();
-        TimerTask timerTask1 = new TimerTask() {
-            @Override
-            public void run() {
                 String time = LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyy-MM"));
-//                KprAimWaterCollecationBizFun.insertYuceDayData(time);
                 KprAimWaterCollecationBizFun.insertYuceDayAddData(time);
-            }
-        };
-        timer.schedule(timerTask1,8000);//8秒后执行一次
-    }
-
-    @PostConstruct
-    public void initWaterHour(){
-        Timer timer = new Timer();
-        TimerTask timerTask1 = new TimerTask() {
-            @Override
-            public void run() {
-                String time = LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyy-MM"));
-//                KprAimWaterCollecationBizFun.insertYuceHourData(time);
                 KprAimWaterCollecationBizFun.insertYuceHourAddData(time);
-                //TODO 实际调用调度模型的接口
-//                KprAimWaterCollecationBizFun.insertYucePump(time);
-            }
-        };
-        timer.schedule(timerTask1,9000);//9秒后执行一次
-        Timer timer2 = new Timer();
-        TimerTask timerTask2 = new TimerTask() {
-            @Override
-            public void run() {
-                String time = LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyy-MM"));
-//                KprAimWaterCollecationBizFun.insertYuceHourDataScheduled(time);//江津的给注释掉
             }
         };
-        timer2.schedule(timerTask2,9000);//9秒后执行一次
+        timer2.schedule(timerTask2,11000);//11秒后执行一次
     }
     //TODO 启动时跑今天泵的数据,江津的先注释
-    @PostConstruct
+    /*@PostConstruct
     public void initPumpFourDay(){
         Timer timer = new Timer();
         TimerTask timerTask1 = new TimerTask() {
@@ -289,38 +254,38 @@ public class ScheduleTaskMgr {
             }
         };
         timer.schedule(timerTask1,9000);//9秒后执行一次
+    }*/
+
+//    TODO 自来水的注释以下俩方法initPumpRecordAll checkPumpRecordAll
+    @PostConstruct
+    public void initPumpRecordAll(){
+        new Timer().schedule(new TimerTask() {
+            @Override
+            public void run() {
+                //当前时间到去年对应月份1号0点开始
+                LocalDateTime firstDayOfLastMonth = LocalDateTime.now().minusMonths(1) // 减去一个月
+                        .toLocalDate()   // 转换为 LocalDate
+                        .withDayOfMonth(1) // 设置为当月的第一天
+                        .atStartOfDay(); // 转换为当天的起始时间
+                String formattedDate = firstDayOfLastMonth.format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"));
+                KprAimTapWaterBizFun.initWaterPumpReacordAll(formattedDate);
+            }
+        },5000);
     }
 
-    //TODO 自来水的注释以下俩方法initPumpRecordAll checkPumpRecordAll
-//    @PostConstruct
-//    public void initPumpRecordAll(){
-//        new Timer().schedule(new TimerTask() {
-//            @Override
-//            public void run() {
-//                //当前时间到去年对应月份1号0点开始
-//                LocalDateTime firstDayOfLastMonth = LocalDateTime.now().minusMonths(1) // 减去一个月
-//                        .toLocalDate()   // 转换为 LocalDate
-//                        .withDayOfMonth(1) // 设置为当月的第一天
-//                        .atStartOfDay(); // 转换为当天的起始时间
-//                String formattedDate = firstDayOfLastMonth.format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"));
-//                KprAimTapWaterBizFun.initWaterPumpReacordAll(formattedDate);
-//            }
-//        },5000);
-//    }
-//
-//    //TODO 每小时的10分执行原始小时泵数据计算
-//    @Scheduled(cron = "0 10 * * * *")
-//    public void checkPumpRecordAll(){
-//        new Timer().schedule(new TimerTask() {
-//            @Override
-//            public void run() {
-//                //当前时间到今天的0点开始
-//                LocalDateTime firstDayOfLastMonth = LocalDate.now().atStartOfDay();//上个月0点
-//                String formattedDate = firstDayOfLastMonth.format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"));
-//                KprAimTapWaterBizFun.initWaterPumpReacordAll(formattedDate);
-//            }
-//        },5000);
-//    }
+    //TODO 每小时的10分执行原始小时泵数据计算
+    @Scheduled(cron = "0 10 * * * *")
+    public void checkPumpRecordAll(){
+        new Timer().schedule(new TimerTask() {
+            @Override
+            public void run() {
+                //当前时间到今天的0点开始
+                LocalDateTime firstDayOfLastMonth = LocalDate.now().atStartOfDay();//上个月0点
+                String formattedDate = firstDayOfLastMonth.format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"));
+                KprAimTapWaterBizFun.initWaterPumpReacordAll(formattedDate);
+            }
+        },5000);
+    }
 
     @PostConstruct
     public void initDatabaseName(){
@@ -331,7 +296,7 @@ public class ScheduleTaskMgr {
                 KprAimWaterCollecationBizFun.initDatabaseName();
             }
         };
-        timer.schedule(timerTask1,6000);//6秒后执行一次
+        timer.schedule(timerTask1,3000);//6秒后执行一次
     }
 
     @Scheduled(cron = "${cron.check.wo.dispatch.plan}")