作者 钟来

解决现网禄辉接口请求超时问题

@@ -2,7 +2,6 @@ package com.zhonglai.luhui.api; @@ -2,7 +2,6 @@ package com.zhonglai.luhui.api;
2 2
3 import org.springframework.boot.SpringApplication; 3 import org.springframework.boot.SpringApplication;
4 import org.springframework.boot.autoconfigure.SpringBootApplication; 4 import org.springframework.boot.autoconfigure.SpringBootApplication;
5 -import org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration;  
6 import org.springframework.context.annotation.ComponentScan; 5 import org.springframework.context.annotation.ComponentScan;
7 import org.springframework.context.annotation.EnableAspectJAutoProxy; 6 import org.springframework.context.annotation.EnableAspectJAutoProxy;
8 7
@@ -8,15 +8,13 @@ import com.zhonglai.luhui.api.controller.data.SensorData; @@ -8,15 +8,13 @@ import com.zhonglai.luhui.api.controller.data.SensorData;
8 import com.zhonglai.luhui.api.controller.data.TableGenerateSqlEnum; 8 import com.zhonglai.luhui.api.controller.data.TableGenerateSqlEnum;
9 import com.zhonglai.luhui.api.mapper.DeviceSensorDataMapper; 9 import com.zhonglai.luhui.api.mapper.DeviceSensorDataMapper;
10 import com.zhonglai.luhui.dao.mapper.PublicMapper; 10 import com.zhonglai.luhui.dao.mapper.PublicMapper;
11 -import com.zhonglai.luhui.datasource.config.DynamicDataSourceContextHolder;  
12 -import com.zhonglai.luhui.datasource.enums.DataSource;  
13 -import com.zhonglai.luhui.datasource.enums.DataSourceType;  
14 import org.springframework.beans.factory.annotation.Autowired; 11 import org.springframework.beans.factory.annotation.Autowired;
15 import org.springframework.stereotype.Service; 12 import org.springframework.stereotype.Service;
16 13
17 import javax.servlet.http.HttpServletResponse; 14 import javax.servlet.http.HttpServletResponse;
18 import java.io.IOException; 15 import java.io.IOException;
19 import java.lang.reflect.Field; 16 import java.lang.reflect.Field;
  17 +import java.text.SimpleDateFormat;
20 import java.util.*; 18 import java.util.*;
21 19
22 @Service 20 @Service
@@ -27,7 +25,6 @@ public class DataService { @@ -27,7 +25,6 @@ public class DataService {
27 @Autowired 25 @Autowired
28 public DeviceSensorDataMapper deviceSensorDataMapper; 26 public DeviceSensorDataMapper deviceSensorDataMapper;
29 27
30 - @DataSource(value = DataSourceType.SLAVE)  
31 public Map<String,Object> getViewDataBeifen(Integer dateTime,String id,String data_type) 28 public Map<String,Object> getViewDataBeifen(Integer dateTime,String id,String data_type)
32 { 29 {
33 30
@@ -273,7 +270,15 @@ public class DataService { @@ -273,7 +270,15 @@ public class DataService {
273 return "取点颗粒必须是10的整数倍,并且不能小于10"; 270 return "取点颗粒必须是10的整数倍,并且不能小于10";
274 } 271 }
275 272
276 - int nowTime = getBeforeDawnTimeMilly(DateUtils.getNowTimeMilly()); //当天凌晨时间 273 + int nowTime = DateUtils.getBeforeDawnTimeMilly(DateUtils.getNowTimeMilly()); //当天凌晨时间
  274 +
  275 + // 计算当前时间的1年后的秒
  276 + long twoYearsLater = nowTime + (365 * 24 * 60 * 60 );
  277 +
  278 + if (endTime > twoYearsLater) {
  279 + response.setStatus(500);
  280 + return "只能查看1年之内的数据,要查看更多数据请联系管理员";
  281 + }
277 282
278 StringBuffer sb = new StringBuffer(); 283 StringBuffer sb = new StringBuffer();
279 if(nowTime>startTime) 284 if(nowTime>startTime)
@@ -285,14 +290,6 @@ public class DataService { @@ -285,14 +290,6 @@ public class DataService {
285 } 290 }
286 291
287 } 292 }
288 - if(endTime > nowTime)  
289 - {  
290 - StringBuffer sbafter = getDeviceTimeData(deviceInfoId,dataType,new Date(endTime*1000l),interval*60);  
291 - if(null != sbafter)  
292 - {  
293 - sb.append(sbafter);  
294 - }  
295 - }  
296 293
297 return sb.toString(); 294 return sb.toString();
298 } 295 }
@@ -303,85 +300,34 @@ public class DataService { @@ -303,85 +300,34 @@ public class DataService {
303 * @param dataType 300 * @param dataType
304 * @return 301 * @return
305 */ 302 */
306 - @DataSource(value = DataSourceType.SLAVE)  
307 public StringBuffer getBeifeiDbDeviceHistoryData(String deviceInfoId,String dataType,int startTime,int endTime,int interval) 303 public StringBuffer getBeifeiDbDeviceHistoryData(String deviceInfoId,String dataType,int startTime,int endTime,int interval)
308 { 304 {
309 - DynamicDataSourceContextHolder.setDataSourceType(DataSourceType.SLAVE.name());  
310 - List<Map<String,Object>> list = publicMapper.getObjectListBySQL("SELECT count(*) ct FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_SCHEMA='ly-device-data' and TABLE_NAME='"+deviceInfoId+"-"+dataType+"'"); 305 + List<String> tableNames = getTableNames(startTime, endTime);
  306 + // 每次查询的最大天数,超过则分批查询
  307 + int BATCH_QUERY_DAYS = 30;
311 308
312 - if(null != list && list.size() !=0 && null != list.get(0) && null != list.get(0).get("ct") && (list.get(0).get("ct")+"").equals("1")) 309 + if(null != tableNames && tableNames.size() !=0 && null != tableNames.get(0) )
313 { 310 {
314 - list = publicMapper.getObjectListBySQL("select *,(`time` % "+interval+") asb from `ly-device-data`.`"+deviceInfoId+"-"+dataType+"` where ((`time` % "+interval+")=0 OR `value`<>'') AND `time`>="+startTime+" and `time`<="+endTime+" order by `time` asc");  
315 -  
316 - if(null != list && list.size() !=0 )  
317 - {  
318 - StringBuffer sb = new StringBuffer();  
319 - 311 + List<DeviceSensorData> deviceSensorDataList = new ArrayList<>();
320 312
321 - for(int i=0;i<list.size();i++)  
322 - {  
323 - Map<String,Object> map = list.get(i);  
324 - if(StringUtils.isNotEmpty((String)map.get("value")))  
325 - {  
326 - sb.append(map.get("time"));  
327 - sb.append(",");  
328 - sb.append(map.get("value"));  
329 - sb.append("\r\n");  
330 - }else{  
331 - String svalue = (String) map.get("value");  
332 - Long sasb = 0l;  
333 - if (i-1>=0)  
334 - { 313 + // **分批查询**(一次最多查 30 天)
  314 + for (int i = 0; i < tableNames.size(); i += BATCH_QUERY_DAYS) {
  315 + int batchStart = i;
  316 + int batchEnd = Math.min(i + BATCH_QUERY_DAYS, tableNames.size());
  317 + List<String> batchTables = tableNames.subList(batchStart, batchEnd);
335 318
336 - String object = (String) list.get(i-1).get("value");  
337 - if((Long) list.get(i-1).get("asb")!=0 && !"".equals(object)){  
338 - svalue = object;  
339 - sasb = (Long) list.get(i-1).get("asb");  
340 - }  
341 -  
342 - }  
343 - String xvalue = (String) map.get("value");  
344 - Long xasb = 0l;  
345 - if (i+1<list.size())  
346 - {  
347 - String object = (String) list.get(i+1).get("value");  
348 - if((Long) list.get(i+1).get("asb")!=0 && !"".equals(object)){  
349 - xvalue = object;  
350 - xasb = (Long) list.get(i+1).get("asb");  
351 - }  
352 - }  
353 -  
354 - if(!"".equals(svalue) && !"".equals(xvalue) )  
355 - {  
356 - if(sasb-xasb>=0)  
357 - {  
358 - sb.append(map.get("time"));  
359 - sb.append(",");  
360 - sb.append(xvalue);  
361 - sb.append("\r\n");  
362 - }else {  
363 - sb.append(map.get("time"));  
364 - sb.append(",");  
365 - sb.append(svalue);  
366 - sb.append("\r\n");  
367 - }  
368 - }else{  
369 - sb.append(map.get("time"));  
370 - sb.append(",");  
371 - sb.append( svalue+""+xvalue);  
372 - sb.append("\r\n");  
373 - }  
374 - }  
375 -  
376 -  
377 - }  
378 - // 销毁数据源 在执行方法之后  
379 - DynamicDataSourceContextHolder.clearDataSourceType();  
380 - return sb; 319 + List<DeviceSensorData> tempDataList = queryBatchTables(batchTables, deviceInfoId, dataType, startTime, endTime);
  320 + deviceSensorDataList.addAll(tempDataList);
  321 + }
  322 + if(null != deviceSensorDataList && deviceSensorDataList.size()!=0)
  323 + {
  324 + //间隔时间补全
  325 + Date sdate = new Date(startTime*1000l);
  326 + String day = DateUtils.parseDateToStr("yyyyMMdd",sdate);
  327 + StringBuffer stringBuffer10 = SensorData.deviceSensorDataListToIntervalCompletion(deviceSensorDataList, Integer.parseInt(sdate.getTime() / 1000 + ""), interval, day);
  328 + return stringBuffer10;
381 } 329 }
382 } 330 }
383 - // 销毁数据源 在执行方法之后  
384 - DynamicDataSourceContextHolder.clearDataSourceType();  
385 return null; 331 return null;
386 } 332 }
387 333
@@ -466,4 +412,45 @@ public class DataService { @@ -466,4 +412,45 @@ public class DataService {
466 CaseFormat toFormat = CaseFormat.LOWER_UNDERSCORE; 412 CaseFormat toFormat = CaseFormat.LOWER_UNDERSCORE;
467 return fromFormat.to(toFormat, s); 413 return fromFormat.to(toFormat, s);
468 } 414 }
  415 +
  416 + /**
  417 + * 根据 startTime 和 endTime 计算查询的表名列表
  418 + */
  419 + private List<String> getTableNames(int startTime, int endTime) {
  420 + List<String> tableNames = new ArrayList<>();
  421 + SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
  422 + Calendar calendar = Calendar.getInstance();
  423 + calendar.setTimeInMillis((long) startTime * 1000);
  424 +
  425 + while (startTime <= endTime) {
  426 + tableNames.add(TableGenerateSqlEnum.DeviceSensorData.getTableName(sdf.format(calendar.getTime())));
  427 + calendar.add(Calendar.DAY_OF_MONTH, 1);
  428 + startTime += 86400; // 加一天(秒)
  429 + }
  430 +
  431 + return tableNames;
  432 + }
  433 +
  434 + /**
  435 + * 查询一批表的数据
  436 + */
  437 + private List<DeviceSensorData> queryBatchTables(List<String> tableNames, String deviceInfoId, String dataType, int startTime, int endTime) {
  438 + StringBuilder sqlBuilder = new StringBuilder();
  439 +
  440 + for (int i = 0; i < tableNames.size(); i++) {
  441 + if (i > 0) {
  442 + sqlBuilder.append(" UNION ALL ");
  443 + }
  444 + sqlBuilder.append("SELECT device_info_id, data_type, data_value, creat_time FROM ")
  445 + .append(tableNames.get(i))
  446 + .append(" WHERE device_info_id = '"+deviceInfoId+"' AND data_type = '"+dataType+"' AND creat_time BETWEEN "+startTime+" AND "+endTime);
  447 + }
  448 +
  449 + sqlBuilder.append(" ORDER BY creat_time ASC");
  450 +
  451 + // **执行 SQL 查询**
  452 + List<DeviceSensorData> deviceSensorDataList = deviceSensorDataMapper.getDeviceSensorDataList(sqlBuilder.toString());
  453 +
  454 + return deviceSensorDataList;
  455 + }
469 } 456 }
@@ -12,10 +12,10 @@ spring: @@ -12,10 +12,10 @@ spring:
12 # 从库数据源 12 # 从库数据源
13 slave: 13 slave:
14 # 从数据源开关/默认关闭 14 # 从数据源开关/默认关闭
15 - enabled: true  
16 - url: jdbc:mysql://rm-wz9a3l0g7cjysv8054o.mysql.rds.aliyuncs.com:3306/ly-device-data?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=true&serverTimezone=GMT%2B8  
17 - username: luhui  
18 - password: Luhui586 15 + enabled: false
  16 + url:
  17 + username:
  18 + password:
19 # 初始连接数 19 # 初始连接数
20 initialSize: 5 20 initialSize: 5
21 # 最小连接池数量 21 # 最小连接池数量
  1 +<configuration>
  2 + <appender name="FILE" class="ch.qos.logback.core.rolling.RollingFileAppender">
  3 + <file>logs/output.log</file>
  4 + <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
  5 + <fileNamePattern>logs/output.%d{yyyy-MM-dd}.log</fileNamePattern>
  6 + <maxHistory>5</maxHistory>
  7 + </rollingPolicy>
  8 + <encoder>
  9 + <pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n</pattern>
  10 + </encoder>
  11 + </appender>
  12 +
  13 + <appender name="CONSOLE" class="ch.qos.logback.core.ConsoleAppender">
  14 + <encoder>
  15 + <pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n</pattern>
  16 + </encoder>
  17 + </appender>
  18 +
  19 + <root level="info">
  20 + <appender-ref ref="FILE" />
  21 + <appender-ref ref="CONSOLE" />
  22 + </root>
  23 +</configuration>