优化agent本地存储流量数据处理
This commit is contained in:
+7
@@ -133,4 +133,11 @@ public interface RemoteRevenueConfigService
|
||||
@GetMapping("/businessScript/inner/{id}")
|
||||
public R<EpsBusinessScriptRemote> getBusinessScriptMsgByScriptId(@PathVariable("id") Long id, @RequestHeader(SecurityConstants.FROM_SOURCE) String source);
|
||||
|
||||
/**
|
||||
* 保存流量数据
|
||||
* @param queryParam 流量数据列表
|
||||
* @return 操作结果
|
||||
*/
|
||||
@PostMapping("/revenueConfig/autoSaveServiceRecoverTrafficData")
|
||||
public R<String> autoSaveServiceRecoverTrafficData(@RequestBody EpsInitialTrafficDataRemote queryParam, @RequestHeader(SecurityConstants.FROM_SOURCE) String source);
|
||||
}
|
||||
|
||||
+5
@@ -96,6 +96,11 @@ public class RemoteRevenueConfigFallbackFactory implements FallbackFactory<Remot
|
||||
public R<EpsBusinessScriptRemote> getBusinessScriptMsgByScriptId(Long id, String source) {
|
||||
return R.fail("获取错误关键词失败:" + throwable.getMessage());
|
||||
}
|
||||
|
||||
@Override
|
||||
public R<String> autoSaveServiceRecoverTrafficData(EpsInitialTrafficDataRemote queryParam, String source) {
|
||||
return R.fail("保存重试流量数据失败:" + throwable.getMessage());
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
+14
-5
@@ -118,7 +118,6 @@ public class EchartsDataUtils {
|
||||
// 准备X轴和Y轴数据
|
||||
List<String> xAxisData = new ArrayList<>();
|
||||
Map<String, Object> yData = new LinkedHashMap<>();
|
||||
|
||||
// 初始化Y轴数据结构
|
||||
dataExtractors.keySet().forEach(name ->
|
||||
yData.put(name, new ArrayList<>()));
|
||||
@@ -152,7 +151,7 @@ public class EchartsDataUtils {
|
||||
seriesData.add(getDefaultValue(name, fixedPercentile95Value, xAxisData.size()-1, hasRealData));
|
||||
} else {
|
||||
// 在数据时间范围外
|
||||
seriesData.add(getEmptyDataDefaultValue(name, xAxisData.size()-1));
|
||||
seriesData.add(getEmptyDataDefaultValue(name, xAxisData.size()-1, hasRealData));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -338,13 +337,23 @@ public class EchartsDataUtils {
|
||||
/**
|
||||
* 获取空数据默认值(用于数据时间范围外的点)
|
||||
*/
|
||||
private static Object getEmptyDataDefaultValue(String metricName, int timeIndex) {
|
||||
private static Object getEmptyDataDefaultValue(String metricName, int timeIndex, boolean hasRealData) {
|
||||
// deployDevice特殊处理:始终补空字符串
|
||||
if ("deployDevice".equals(metricName)) {
|
||||
return "";
|
||||
}
|
||||
|
||||
return null;
|
||||
// 智能补全策略
|
||||
if (hasRealData) {
|
||||
// 数据集中有真实数据:所有缺失点都补null
|
||||
return null;
|
||||
} else {
|
||||
// 数据集中没有真实数据:第一个点补0,其他点补null
|
||||
if (timeIndex == 0) {
|
||||
return 0;
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
+9
@@ -79,5 +79,14 @@ public class EpsServerRevenueConfigController extends BaseController
|
||||
{
|
||||
return epsServerRevenueConfigService.autoSaveServiceTrafficData(epsServerRevenueConfig);
|
||||
}
|
||||
/**
|
||||
* 流量相关数据入库
|
||||
*/
|
||||
@InnerAuth
|
||||
@PostMapping("/autoSaveServiceRecoverTrafficData")
|
||||
public R<String> autoSaveServiceRecoverTrafficData(@RequestBody EpsServerRevenueConfig epsServerRevenueConfig)
|
||||
{
|
||||
return epsServerRevenueConfigService.autoSaveServiceRecoverTrafficData(epsServerRevenueConfig);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
+2
@@ -74,4 +74,6 @@ public interface EpsInitialTrafficDataMapper {
|
||||
void createSwitchOpMdTable(String tableName);
|
||||
|
||||
void createDiskInfo(String tableName);
|
||||
|
||||
void batchInsertRecoverDetailTraffic(EpsInitialTrafficData batchData);
|
||||
}
|
||||
|
||||
+1
@@ -36,6 +36,7 @@ public interface EpsInitialTrafficDataService {
|
||||
* @param dataList 流量数据列表
|
||||
*/
|
||||
void saveBatch(EpsInitialTrafficData dataList);
|
||||
void saveBatchRecoverTraffic(EpsInitialTrafficData dataList);
|
||||
|
||||
/**
|
||||
* 查询流量数据
|
||||
|
||||
+1
@@ -67,6 +67,7 @@ public interface IEpsServerRevenueConfigService
|
||||
* @param epsServerRevenueConfig
|
||||
*/
|
||||
R<String> autoSaveServiceTrafficData(EpsServerRevenueConfig epsServerRevenueConfig);
|
||||
R<String> autoSaveServiceRecoverTrafficData(EpsServerRevenueConfig epsServerRevenueConfig);
|
||||
/**
|
||||
* 当前在线服务器的流量相关的业务数
|
||||
* @return
|
||||
|
||||
+67
@@ -245,6 +245,73 @@ public class EpsInitialTrafficDataServiceImpl implements EpsInitialTrafficDataSe
|
||||
}
|
||||
});
|
||||
}
|
||||
/**
|
||||
* 批量保存数据到对应分表
|
||||
* @param epsInitialTrafficData 流量数据表
|
||||
*/
|
||||
@Override
|
||||
@Transactional(rollbackFor = Exception.class, isolation = Isolation.READ_COMMITTED)
|
||||
public void saveBatchRecoverTraffic(EpsInitialTrafficData epsInitialTrafficData) {
|
||||
if (epsInitialTrafficData == null || epsInitialTrafficData.getDataList().isEmpty()) {
|
||||
return;
|
||||
}
|
||||
|
||||
// 内存去重(基于唯一键)
|
||||
List<EpsInitialTrafficData> distinctList = epsInitialTrafficData.getDataList().stream()
|
||||
.filter(Objects::nonNull)
|
||||
.map(data -> {
|
||||
EpsInitialTrafficData processed = new EpsInitialTrafficData();
|
||||
BeanUtils.copyProperties(data, processed);
|
||||
if (data.getCreateTime() == null) {
|
||||
processed.setCreateTime(DateUtils.getNowDate());
|
||||
}
|
||||
return processed;
|
||||
})
|
||||
.collect(Collectors.collectingAndThen(
|
||||
// 使用TreeSet按唯一键去重
|
||||
Collectors.toCollection(() -> new TreeSet<>(Comparator.comparing(
|
||||
d -> String.join("|",
|
||||
d.getClientId(),
|
||||
d.getMac(),
|
||||
d.getName(),
|
||||
d.getCreateTime().toString()
|
||||
)
|
||||
))),
|
||||
ArrayList::new
|
||||
));
|
||||
|
||||
// 按表名分组
|
||||
Map<String, List<EpsInitialTrafficData>> groupedData = distinctList.stream()
|
||||
.map(data -> {
|
||||
data.setTableName(TableRouterUtil.getTableName(
|
||||
data.getCreateTime().toInstant()
|
||||
.atZone(ZoneId.systemDefault())
|
||||
.toLocalDateTime()
|
||||
));
|
||||
return data;
|
||||
})
|
||||
.collect(Collectors.groupingBy(
|
||||
EpsInitialTrafficData::getTableName,
|
||||
LinkedHashMap::new,
|
||||
Collectors.toList()
|
||||
));
|
||||
|
||||
// 分表插入(带冲突降级)
|
||||
groupedData.forEach((tableName, list) -> {
|
||||
try {
|
||||
EpsInitialTrafficData batchData = new EpsInitialTrafficData();
|
||||
BeanUtils.copyProperties(epsInitialTrafficData, batchData);
|
||||
batchData.setTableName(tableName);
|
||||
batchData.setDataList(list);
|
||||
|
||||
// 优先尝试批量插入
|
||||
epsInitialTrafficDataMapper.batchInsertRecoverDetailTraffic(batchData);
|
||||
} catch (Exception e) {
|
||||
log.error("表 {} 插入失败", tableName, e);
|
||||
throw new RuntimeException("数据入库失败", e);
|
||||
}
|
||||
});
|
||||
}
|
||||
/**
|
||||
* 查询流量数据
|
||||
*/
|
||||
|
||||
+96
@@ -259,6 +259,102 @@ public class EpsServerRevenueConfigServiceImpl implements IEpsServerRevenueConfi
|
||||
return R.fail("数据保存失败:" + e.getMessage() + ",已成功保存" + successCount + "条");
|
||||
}
|
||||
}
|
||||
/**
|
||||
* 保存流量信息
|
||||
* @param epsServerRevenueConfig
|
||||
*/
|
||||
@Override
|
||||
public R<String> autoSaveServiceRecoverTrafficData(EpsServerRevenueConfig epsServerRevenueConfig) {
|
||||
// 查询初始流量数据
|
||||
EpsInitialTrafficData epsInitialTrafficData = new EpsInitialTrafficData();
|
||||
epsInitialTrafficData.setStartTime(epsServerRevenueConfig.getStartTime());
|
||||
epsInitialTrafficData.setEndTime(epsServerRevenueConfig.getEndTime());
|
||||
List<EpsInitialTrafficData> dataList = epsInitialTrafficDataService.getAllTraficMsg(epsInitialTrafficData);
|
||||
|
||||
if (dataList == null || dataList.isEmpty()) {
|
||||
return R.ok("没有需要处理的数据");
|
||||
}
|
||||
|
||||
List<EpsInitialTrafficData> batchList = new ArrayList<>();
|
||||
int batchSize = 1000; // 每批处理数量
|
||||
int totalCount = 0;
|
||||
int successCount = 0;
|
||||
int batchNumber = 0;
|
||||
|
||||
try {
|
||||
for (EpsInitialTrafficData initialTrafficData : dataList) {
|
||||
// 根据clientId查询业务名称
|
||||
RmResourceRegistration rmResourceRegistration = new RmResourceRegistration();
|
||||
rmResourceRegistration.setClientId(initialTrafficData.getClientId());
|
||||
List<RmResourceRegistration> registerLst = rmResourceRegistrationMapper.selectRmResourceRegistrationList(rmResourceRegistration);
|
||||
|
||||
if(registerLst != null && !registerLst.isEmpty()){
|
||||
RmResourceRegistration registerMsg = registerLst.get(0);
|
||||
// 赋值
|
||||
if(registerMsg != null){
|
||||
String businessName = registerMsg.getBusinessName();
|
||||
if(businessName != null){
|
||||
initialTrafficData.setBusinessName(businessName);
|
||||
// 根据业务名称查询业务代码
|
||||
EpsBusiness epsBusiness = epsBusinessMapper.selectEpsBusinessByName(businessName);
|
||||
if(epsBusiness != null){
|
||||
initialTrafficData.setBusinessId(epsBusiness.getId());
|
||||
}
|
||||
}
|
||||
initialTrafficData.setServiceSn(registerMsg.getHardwareSn());
|
||||
initialTrafficData.setRevenueMethod("1");
|
||||
}
|
||||
}
|
||||
// id自增
|
||||
initialTrafficData.setId(null);
|
||||
batchList.add(initialTrafficData);
|
||||
|
||||
// 达到批次大小时保存
|
||||
if (batchList.size() >= batchSize) {
|
||||
batchNumber++;
|
||||
totalCount += batchList.size();
|
||||
epsInitialTrafficData.setDataList(batchList);
|
||||
epsInitialTrafficDataService.saveBatchRecoverTraffic(epsInitialTrafficData);
|
||||
log.info("第{}批流量数据批量入库成功,数据量:{}", batchNumber, batchList.size());
|
||||
|
||||
// 处理接口名称
|
||||
processInterfaceNames(batchList);
|
||||
|
||||
successCount += batchList.size();
|
||||
// 清空当前批次,准备下一批
|
||||
batchList = new ArrayList<>();
|
||||
}
|
||||
}
|
||||
|
||||
// 处理最后一批不足1000条的数据
|
||||
if (!batchList.isEmpty()) {
|
||||
batchNumber++;
|
||||
totalCount += batchList.size();
|
||||
epsInitialTrafficData.setDataList(batchList);
|
||||
epsInitialTrafficDataService.saveBatchRecoverTraffic(epsInitialTrafficData);
|
||||
log.info("第{}批流量数据批量入库成功,数据量:{}", batchNumber, batchList.size());
|
||||
|
||||
// 处理最后一批的接口名称
|
||||
processInterfaceNames(batchList);
|
||||
|
||||
successCount += batchList.size();
|
||||
}
|
||||
|
||||
log.info("流量数据批量入库完成,总批次数:{},总数据量:{},成功数量:{}",
|
||||
batchNumber, totalCount, successCount);
|
||||
|
||||
if (successCount == totalCount) {
|
||||
return R.ok("数据保存成功,共处理" + successCount + "条数据");
|
||||
} else {
|
||||
return R.fail("数据保存部分成功,应处理" + totalCount + "条,实际成功" + successCount + "条");
|
||||
}
|
||||
|
||||
} catch (Exception e) {
|
||||
log.error("流量数据入库失败,已处理批次:{},成功数量:{},当前批次数量:{},错误原因:{}",
|
||||
batchNumber, successCount, batchList.size(), e.getMessage(), e);
|
||||
return R.fail("数据保存失败:" + e.getMessage() + ",已成功保存" + successCount + "条");
|
||||
}
|
||||
}
|
||||
/**
|
||||
* 当前在线服务器的流量相关的业务数
|
||||
* @return
|
||||
|
||||
+85
@@ -377,6 +377,91 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
|
||||
)
|
||||
</foreach>
|
||||
</insert>
|
||||
<insert id="batchInsertRecoverDetailTraffic">
|
||||
INSERT INTO ${tableName} (
|
||||
id,
|
||||
`name`,
|
||||
`mac`,
|
||||
`status`,
|
||||
`type`,
|
||||
ipV4,
|
||||
`in_dropped`,
|
||||
`out_dropped`,
|
||||
`in_speed`,
|
||||
`out_speed`,
|
||||
`total_in_speed`,
|
||||
`total_out_speed`,
|
||||
`speed`,
|
||||
`duplex`,
|
||||
business_id,
|
||||
business_name,
|
||||
service_sn,
|
||||
node_name,
|
||||
revenue_method,
|
||||
package_bandwidth,
|
||||
create_time,
|
||||
update_time,
|
||||
create_by,
|
||||
update_by,
|
||||
client_id,
|
||||
ipv4_in_speed,
|
||||
ipv4_out_speed,
|
||||
ipv6_in_speed,
|
||||
ipv6_out_speed,
|
||||
total_ipv4_in_speed,
|
||||
total_ipv4_out_speed,
|
||||
total_ipv6_in_speed,
|
||||
total_ipv6_out_speed,
|
||||
ipV6,
|
||||
ping_dropped
|
||||
) VALUES
|
||||
<foreach collection="dataList" item="data" separator=",">
|
||||
(
|
||||
#{data.id,jdbcType=BIGINT},
|
||||
#{data.name,jdbcType=VARCHAR},
|
||||
#{data.mac,jdbcType=VARCHAR},
|
||||
#{data.status,jdbcType=VARCHAR},
|
||||
#{data.type,jdbcType=VARCHAR},
|
||||
#{data.ipV4,jdbcType=VARCHAR},
|
||||
#{data.inDropped,jdbcType=DECIMAL},
|
||||
#{data.outDropped,jdbcType=DECIMAL},
|
||||
#{data.inSpeed,jdbcType=VARCHAR},
|
||||
#{data.outSpeed,jdbcType=VARCHAR},
|
||||
#{data.totalInSpeed,jdbcType=VARCHAR},
|
||||
#{data.totalOutSpeed,jdbcType=VARCHAR},
|
||||
#{data.speed,jdbcType=VARCHAR},
|
||||
#{data.duplex,jdbcType=VARCHAR},
|
||||
#{data.businessId,jdbcType=VARCHAR},
|
||||
#{data.businessName,jdbcType=VARCHAR},
|
||||
#{data.serviceSn,jdbcType=VARCHAR},
|
||||
#{data.nodeName,jdbcType=VARCHAR},
|
||||
#{data.revenueMethod,jdbcType=VARCHAR},
|
||||
#{data.packageBandwidth,jdbcType=DECIMAL},
|
||||
#{data.createTime,jdbcType=TIMESTAMP},
|
||||
#{data.updateTime,jdbcType=TIMESTAMP},
|
||||
#{data.createBy,jdbcType=VARCHAR},
|
||||
#{data.updateBy,jdbcType=VARCHAR},
|
||||
#{data.clientId,jdbcType=VARCHAR},
|
||||
#{data.ipv4InSpeed,jdbcType=VARCHAR},
|
||||
#{data.ipv4OutSpeed,jdbcType=VARCHAR},
|
||||
#{data.ipv6InSpeed,jdbcType=VARCHAR},
|
||||
#{data.ipv6OutSpeed,jdbcType=VARCHAR},
|
||||
#{data.totalIpv4InSpeed,jdbcType=VARCHAR},
|
||||
#{data.totalIpv4OutSpeed,jdbcType=VARCHAR},
|
||||
#{data.totalIpv6InSpeed,jdbcType=VARCHAR},
|
||||
#{data.totalIpv6OutSpeed,jdbcType=VARCHAR},
|
||||
#{data.ipV6,jdbcType=VARCHAR},
|
||||
#{data.pingDropped,jdbcType=DECIMAL}
|
||||
)
|
||||
</foreach>
|
||||
ON DUPLICATE KEY UPDATE
|
||||
`in_speed` = IF(VALUES(`in_speed`) IS NOT NULL, VALUES(`in_speed`), `in_speed`),
|
||||
`out_speed` = IF(VALUES(`out_speed`) IS NOT NULL, VALUES(`out_speed`), `out_speed`),
|
||||
`ipv4_in_speed` = IF(VALUES(`ipv4_in_speed`) IS NOT NULL, VALUES(`ipv4_in_speed`), `ipv4_in_speed`),
|
||||
`ipv4_out_speed` = IF(VALUES(`ipv4_out_speed`) IS NOT NULL, VALUES(`ipv4_out_speed`), `ipv4_out_speed`),
|
||||
`ipv6_in_speed` = IF(VALUES(`ipv6_in_speed`) IS NOT NULL, VALUES(`ipv6_in_speed`), `ipv6_in_speed`),
|
||||
`ipv6_out_speed` = IF(VALUES(`ipv6_out_speed`) IS NOT NULL, VALUES(`ipv6_out_speed`), `ipv6_out_speed`)
|
||||
</insert>
|
||||
|
||||
<!-- 条件查询 -->
|
||||
<select id="selectByCondition" resultType="EpsInitialTrafficData">
|
||||
|
||||
@@ -721,23 +721,31 @@ public class MessageHandler {
|
||||
long millis = timestamp * 1000;
|
||||
Date createTime = new Date(millis / 1000 * 1000); // 去除毫秒
|
||||
String timeStr = DateUtils.parseDateToStr("yyyy-MM-dd HH:mm:ss",createTime);
|
||||
|
||||
// 判断数据库中是否已存在数据
|
||||
InitialBandwidthTraffic countQuery = new InitialBandwidthTraffic();
|
||||
countQuery.setClientId(clientId);
|
||||
countQuery.setCreateTime(createTime);
|
||||
countQuery.setStartTime(timeStr);
|
||||
int exitsCount = initialBandwidthTrafficService.countByClientIdAndTime(countQuery);
|
||||
|
||||
// 即使数据已存在,也需要处理临时表逻辑,确保后续计算正确
|
||||
if(exitsCount > 0){
|
||||
return;
|
||||
// 不直接返回,继续执行临时表处理逻辑
|
||||
// 但跳过最终的数据入库操作
|
||||
System.out.println("数据已存在,跳过入库操作,但继续处理临时表逻辑");
|
||||
}
|
||||
|
||||
// 创建比timestamp少5分钟的时间
|
||||
long fiveMinutesEarlier = millis - (5 * 60 * 1000); // 减去5分钟的毫秒数
|
||||
Date fiveMinutesEarlierDate = new Date(fiveMinutesEarlier / 1000 * 1000); // 同样去除毫秒
|
||||
|
||||
// 查询临时表信息,计算实际流量值
|
||||
InitialBandwidthTrafficTemp temp = new InitialBandwidthTrafficTemp();
|
||||
temp.setCreateTime(fiveMinutesEarlierDate);
|
||||
temp.setClientId(clientId);
|
||||
List<InitialBandwidthTrafficTemp> tempList = initialBandwidthTrafficTempService.selectInitialBandwidthTrafficRecoverTempList(temp);
|
||||
|
||||
if(!tempList.isEmpty()){
|
||||
// 1. 构建快速查找的Map,使用MAC地址+网卡名称作为唯一键
|
||||
Map<String, InitialBandwidthTrafficTemp> tempMap = tempList.stream()
|
||||
@@ -834,7 +842,7 @@ public class MessageHandler {
|
||||
delQuery.setClientId(clientId);
|
||||
delQuery.setCreateTime(fiveMinutesEarlierDate);
|
||||
initialBandwidthTrafficTempService.deleteTempMsgByClientIdAndTime(delQuery);
|
||||
}else{
|
||||
} else {
|
||||
interfaces.forEach(iface -> {
|
||||
iface.setClientId(clientId);
|
||||
iface.setCreateTime(createTime);
|
||||
@@ -855,19 +863,26 @@ public class MessageHandler {
|
||||
iface.setIpv6OutSpeed(null);
|
||||
});
|
||||
}
|
||||
InitialBandwidthTraffic data = new InitialBandwidthTraffic();
|
||||
// 批量入库集合
|
||||
data.setList(interfaces);
|
||||
// 临时表 用来计算流量速率
|
||||
initialBandwidthTrafficTempService.batchInsertServerRecoverTemp(interfaces);
|
||||
// 初始流量数据入库
|
||||
initialBandwidthTrafficService.batchInsert(data);
|
||||
EpsInitialTrafficDataRemote epsInitialTrafficDataRemote = new EpsInitialTrafficDataRemote();
|
||||
epsInitialTrafficDataRemote.setStartTime(timeStr);
|
||||
epsInitialTrafficDataRemote.setEndTime(timeStr);
|
||||
// 复制到业务初始库
|
||||
remoteRevenueConfigService.autoSaveServiceTrafficData(epsInitialTrafficDataRemote, SecurityConstants.INNER);
|
||||
}else{
|
||||
|
||||
// 只有在数据不存在时才执行入库操作
|
||||
if (exitsCount == 0) {
|
||||
InitialBandwidthTraffic data = new InitialBandwidthTraffic();
|
||||
// 批量入库集合
|
||||
data.setList(interfaces);
|
||||
// 临时表 用来计算流量速率
|
||||
initialBandwidthTrafficTempService.batchInsertServerRecoverTemp(interfaces);
|
||||
// 初始流量数据入库
|
||||
initialBandwidthTrafficService.batchInsertRecoverTraffic(data);
|
||||
EpsInitialTrafficDataRemote epsInitialTrafficDataRemote = new EpsInitialTrafficDataRemote();
|
||||
epsInitialTrafficDataRemote.setStartTime(timeStr);
|
||||
epsInitialTrafficDataRemote.setEndTime(timeStr);
|
||||
// 复制到业务初始库
|
||||
remoteRevenueConfigService.autoSaveServiceRecoverTrafficData(epsInitialTrafficDataRemote, SecurityConstants.INNER);
|
||||
} else {
|
||||
// 数据已存在时,只更新临时表,确保后续计算正确
|
||||
initialBandwidthTrafficTempService.batchInsertServerRecoverTemp(interfaces);
|
||||
}
|
||||
} else {
|
||||
throw new RuntimeException("NET流量data数据为空");
|
||||
}
|
||||
}
|
||||
@@ -971,77 +986,77 @@ public class MessageHandler {
|
||||
long timestamp = disks.get(0).getTimestamp();
|
||||
long millis = timestamp * 1000;
|
||||
Date createTime = new Date(millis / 1000 * 1000);
|
||||
disks.forEach(disk -> {
|
||||
disk.setClientId(clientId);
|
||||
disk.setCreateTime(createTime);
|
||||
});
|
||||
// 关键:每个clientId有自己独立的key
|
||||
// String diskCountKey = DISK_COUNT_PREFIX + clientId;
|
||||
//
|
||||
// // 1. 给这个客户端的所有磁盘次数+1
|
||||
// Map<Object, Object> diskCountMap = redisTemplate.opsForHash().entries(diskCountKey);
|
||||
// for (Map.Entry<Object, Object> entry : diskCountMap.entrySet()) {
|
||||
// String diskName = (String) entry.getKey();
|
||||
// String countStr = (String) entry.getValue();
|
||||
//
|
||||
// try {
|
||||
// int count = Integer.parseInt(countStr) + 1;
|
||||
// redisTemplate.opsForHash().put(diskCountKey, diskName, String.valueOf(count));
|
||||
// } catch (NumberFormatException e) {
|
||||
// redisTemplate.opsForHash().put(diskCountKey, diskName, "1");
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// // 2. 处理本次上报的磁盘
|
||||
// Set<String> reportedDisks = new HashSet<>();
|
||||
// disks.forEach(disk -> {
|
||||
// String diskName = disk.getName();
|
||||
// reportedDisks.add(diskName);
|
||||
//
|
||||
// // 本次上报的磁盘,次数重置为0
|
||||
// redisTemplate.opsForHash().put(diskCountKey, diskName, "0");
|
||||
//
|
||||
// disk.setClientId(clientId);
|
||||
// disk.setCreateTime(createTime);
|
||||
// });
|
||||
//
|
||||
// // 3. 检查次数≥3的磁盘
|
||||
// diskCountMap = redisTemplate.opsForHash().entries(diskCountKey);
|
||||
// List<String> disksToRemove = new ArrayList<>();
|
||||
//
|
||||
// for (Map.Entry<Object, Object> entry : diskCountMap.entrySet()) {
|
||||
// String diskName = (String) entry.getKey();
|
||||
// String countStr = (String) entry.getValue();
|
||||
//
|
||||
// try {
|
||||
// int count = Integer.parseInt(countStr);
|
||||
// // 如果次数≥3且本次没上报
|
||||
// if (count >= 3 && !reportedDisks.contains(diskName)) {
|
||||
// AllDiskName allDiskName = new AllDiskName();
|
||||
// allDiskName.setStatus(0);
|
||||
// allDiskName.setClientId(clientId);
|
||||
// allDiskName.setName(diskName);
|
||||
// allDiskNameService.updateAllDiskName(allDiskName);
|
||||
// disksToRemove.add(diskName);
|
||||
// // 磁盘缺失,触发告警
|
||||
// RmAlarmLog rmAlarmLog = new RmAlarmLog();
|
||||
// rmAlarmLog.setClientId(clientId);
|
||||
// rmAlarmLog.setAlarmTime(DateUtils.getNowDate());
|
||||
// rmAlarmLog.setAlarmType(AlarmTypeEnum.磁盘缺失.getCode());
|
||||
// rmAlarmLog.setAlarmContent("服务器" + clientId + "磁盘缺失,磁盘名称:" + diskName);
|
||||
// rmAlarmLogService.insertRmAlarmLog(rmAlarmLog);
|
||||
// sendAlarmPushUtil.sendAlarmPush(rmAlarmLog, AlarmTypeEnum.磁盘缺失.getMsg());
|
||||
//
|
||||
// }
|
||||
// } catch (NumberFormatException e) {
|
||||
// disksToRemove.add(diskName);
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// // 4. 删除已处理的磁盘记录
|
||||
// if (!disksToRemove.isEmpty()) {
|
||||
// redisTemplate.opsForHash().delete(diskCountKey, disksToRemove.toArray());
|
||||
// }
|
||||
// 关键:每个clientId有自己独立的key
|
||||
String diskCountKey = DISK_COUNT_PREFIX + clientId;
|
||||
|
||||
// 1. 给这个客户端的所有磁盘次数+1
|
||||
Map<Object, Object> diskCountMap = redisTemplate.opsForHash().entries(diskCountKey);
|
||||
for (Map.Entry<Object, Object> entry : diskCountMap.entrySet()) {
|
||||
String diskName = (String) entry.getKey();
|
||||
String countStr = (String) entry.getValue();
|
||||
|
||||
try {
|
||||
int count = Integer.parseInt(countStr) + 1;
|
||||
redisTemplate.opsForHash().put(diskCountKey, diskName, String.valueOf(count));
|
||||
} catch (NumberFormatException e) {
|
||||
redisTemplate.opsForHash().put(diskCountKey, diskName, "1");
|
||||
}
|
||||
}
|
||||
|
||||
// 2. 处理本次上报的磁盘
|
||||
Set<String> reportedDisks = new HashSet<>();
|
||||
disks.forEach(disk -> {
|
||||
String diskName = disk.getName();
|
||||
reportedDisks.add(diskName);
|
||||
|
||||
// 本次上报的磁盘,次数重置为0
|
||||
redisTemplate.opsForHash().put(diskCountKey, diskName, "0");
|
||||
|
||||
disk.setClientId(clientId);
|
||||
disk.setCreateTime(createTime);
|
||||
});
|
||||
|
||||
// 3. 检查次数≥3的磁盘
|
||||
diskCountMap = redisTemplate.opsForHash().entries(diskCountKey);
|
||||
List<String> disksToRemove = new ArrayList<>();
|
||||
|
||||
for (Map.Entry<Object, Object> entry : diskCountMap.entrySet()) {
|
||||
String diskName = (String) entry.getKey();
|
||||
String countStr = (String) entry.getValue();
|
||||
|
||||
try {
|
||||
int count = Integer.parseInt(countStr);
|
||||
// 如果次数≥3且本次没上报
|
||||
if (count >= 3 && !reportedDisks.contains(diskName)) {
|
||||
AllDiskName allDiskName = new AllDiskName();
|
||||
allDiskName.setStatus(0);
|
||||
allDiskName.setClientId(clientId);
|
||||
allDiskName.setName(diskName);
|
||||
allDiskNameService.updateAllDiskName(allDiskName);
|
||||
disksToRemove.add(diskName);
|
||||
// 磁盘缺失,触发告警
|
||||
RmAlarmLog rmAlarmLog = new RmAlarmLog();
|
||||
rmAlarmLog.setClientId(clientId);
|
||||
rmAlarmLog.setAlarmTime(DateUtils.getNowDate());
|
||||
rmAlarmLog.setAlarmType(AlarmTypeEnum.磁盘缺失.getCode());
|
||||
rmAlarmLog.setAlarmContent("服务器" + clientId + "磁盘缺失,磁盘名称:" + diskName);
|
||||
rmAlarmLogService.insertRmAlarmLog(rmAlarmLog);
|
||||
sendAlarmPushUtil.sendAlarmPush(rmAlarmLog, AlarmTypeEnum.磁盘缺失.getMsg());
|
||||
|
||||
}
|
||||
} catch (NumberFormatException e) {
|
||||
disksToRemove.add(diskName);
|
||||
}
|
||||
}
|
||||
|
||||
// 4. 删除已处理的磁盘记录
|
||||
if (!disksToRemove.isEmpty()) {
|
||||
redisTemplate.opsForHash().delete(diskCountKey, disksToRemove.toArray());
|
||||
}
|
||||
|
||||
// 5. 数据入库
|
||||
initialDiskInfoService.batchInsertInitialDiskInfo(disks, createTime);
|
||||
@@ -1961,7 +1976,7 @@ public class MessageHandler {
|
||||
* 查询IP地址归属地信息,返回运营商和省份
|
||||
*/
|
||||
private Map<String, String> queryIpLocation(String ip) {
|
||||
String apiUrl = "http://172.16.15.51:10000/?ip=" + ip;
|
||||
String apiUrl = "http://172.16.15.103:10000/?ip=" + ip;
|
||||
CloseableHttpClient httpClient = HttpClients.createDefault();
|
||||
HttpGet httpGet = new HttpGet(apiUrl);
|
||||
|
||||
|
||||
+1
@@ -71,6 +71,7 @@ public interface InitialBandwidthTrafficMapper
|
||||
* @param data 流量数据实体类
|
||||
*/
|
||||
int batchInsert(InitialBandwidthTraffic data);
|
||||
int batchInsertRecoverTraffic(InitialBandwidthTraffic data);
|
||||
/**
|
||||
* 网络接口基础信息
|
||||
* @param initialBandwidthTraffic
|
||||
|
||||
+1
@@ -71,6 +71,7 @@ public interface IInitialBandwidthTrafficService
|
||||
* @param data 流量数据
|
||||
*/
|
||||
void batchInsert(InitialBandwidthTraffic data);
|
||||
void batchInsertRecoverTraffic(InitialBandwidthTraffic data);
|
||||
/**
|
||||
* 网络接口基础信息
|
||||
* @param initialBandwidthTraffic
|
||||
|
||||
+50
@@ -183,6 +183,56 @@ public class InitialBandwidthTrafficServiceImpl implements IInitialBandwidthTraf
|
||||
}
|
||||
});
|
||||
}
|
||||
/**
|
||||
* 保存多条数据到对应分表
|
||||
* @param initialBandwidthTraffic 流量数据
|
||||
*/
|
||||
@Override
|
||||
@Transactional(rollbackFor = Exception.class, isolation = Isolation.READ_COMMITTED)
|
||||
public void batchInsertRecoverTraffic(InitialBandwidthTraffic initialBandwidthTraffic) {
|
||||
if (initialBandwidthTraffic == null) {
|
||||
return;
|
||||
}
|
||||
List<InitialBandwidthTraffic> dataList = initialBandwidthTraffic.getList();
|
||||
if (dataList.isEmpty()){
|
||||
return;
|
||||
}
|
||||
// 按表名分组批量插入
|
||||
Map<String, List<InitialBandwidthTraffic>> groupedData = dataList.stream()
|
||||
.map(data -> {
|
||||
try {
|
||||
InitialBandwidthTraffic processed = new InitialBandwidthTraffic();
|
||||
BeanUtils.copyProperties(data,processed);
|
||||
if (data.getCreateTime() == null) {
|
||||
data.setCreateTime(DateUtils.getNowDate());
|
||||
}
|
||||
LocalDateTime createTime = data.getCreateTime().toInstant()
|
||||
.atZone(ZoneId.systemDefault())
|
||||
.toLocalDateTime();
|
||||
processed.setTableName(TableRouterUtil.getTableName(createTime));
|
||||
return processed;
|
||||
} catch (Exception e){
|
||||
log.error("数据处理失败",e.getMessage());
|
||||
return null;
|
||||
}
|
||||
}).collect(Collectors.groupingBy(
|
||||
InitialBandwidthTraffic::getTableName,
|
||||
LinkedHashMap::new, // 保持插入顺序
|
||||
Collectors.toList()));
|
||||
|
||||
groupedData.forEach((tableName, list) -> {
|
||||
try {
|
||||
InitialBandwidthTraffic data = new InitialBandwidthTraffic();
|
||||
BeanUtils.copyProperties(initialBandwidthTraffic,data);
|
||||
data.setTableName(tableName);
|
||||
data.setList(list);
|
||||
initialBandwidthTrafficMapper.batchInsertRecoverTraffic(data);
|
||||
} catch (Exception e) {
|
||||
log.error("表{}插入失败", tableName, e);
|
||||
throw new RuntimeException("批量插入失败", e);
|
||||
}
|
||||
});
|
||||
}
|
||||
/**
|
||||
* 网络接口基础信息
|
||||
* @param initialBandwidthTraffic
|
||||
|
||||
+28
-1
@@ -143,7 +143,33 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
|
||||
)
|
||||
</foreach>
|
||||
</insert>
|
||||
|
||||
<insert id="batchInsertRecoverTraffic" parameterType="InitialBandwidthTraffic">
|
||||
INSERT INTO ${tableName} (
|
||||
`name`, `mac`, `status`, `type`, ipV4, `in_dropped`, `out_dropped`,
|
||||
`in_speed`, `out_speed`, `total_in_speed`, `total_out_speed`, duplex, speed,
|
||||
create_by, update_by, client_id, create_time,
|
||||
ipv4_in_speed, ipv4_out_speed, ipv6_in_speed, ipv6_out_speed,
|
||||
total_ipv4_in_speed, total_ipv4_out_speed, total_ipv6_in_speed, total_ipv6_out_speed,
|
||||
ipV6, ping_dropped
|
||||
) VALUES
|
||||
<foreach collection="list" item="item" separator=",">
|
||||
(
|
||||
#{item.name}, #{item.mac}, #{item.status}, #{item.type}, #{item.ipV4}, #{item.inDropped}, #{item.outDropped},
|
||||
#{item.inSpeed}, #{item.outSpeed}, #{item.totalInSpeed}, #{item.totalOutSpeed}, #{item.duplex}, #{item.speed},
|
||||
#{item.createBy}, #{item.updateBy}, #{item.clientId}, #{item.createTime},
|
||||
#{item.ipv4InSpeed}, #{item.ipv4OutSpeed}, #{item.ipv6InSpeed}, #{item.ipv6OutSpeed},
|
||||
#{item.totalIpv4InSpeed}, #{item.totalIpv4OutSpeed}, #{item.totalIpv6InSpeed}, #{item.totalIpv6OutSpeed},
|
||||
#{item.ipV6}, #{item.pingDropped}
|
||||
)
|
||||
</foreach>
|
||||
ON DUPLICATE KEY UPDATE
|
||||
`in_speed` = IF(VALUES(`in_speed`) IS NOT NULL, VALUES(`in_speed`), `in_speed`),
|
||||
`out_speed` = IF(VALUES(`out_speed`) IS NOT NULL, VALUES(`out_speed`), `out_speed`),
|
||||
`ipv4_in_speed` = IF(VALUES(`ipv4_in_speed`) IS NOT NULL, VALUES(`ipv4_in_speed`), `ipv4_in_speed`),
|
||||
`ipv4_out_speed` = IF(VALUES(`ipv4_out_speed`) IS NOT NULL, VALUES(`ipv4_out_speed`), `ipv4_out_speed`),
|
||||
`ipv6_in_speed` = IF(VALUES(`ipv6_in_speed`) IS NOT NULL, VALUES(`ipv6_in_speed`), `ipv6_in_speed`),
|
||||
`ipv6_out_speed` = IF(VALUES(`ipv6_out_speed`) IS NOT NULL, VALUES(`ipv6_out_speed`), `ipv6_out_speed`)
|
||||
</insert>
|
||||
<select id="getNetInterfaceDetailsMsg" parameterType="InitialBandwidthTraffic" resultType="InitialBandwidthTraffic">
|
||||
select
|
||||
id,
|
||||
@@ -229,6 +255,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
|
||||
<where>
|
||||
<if test="clientId != null and clientId != ''"> and client_id = #{clientId}</if>
|
||||
<if test="startTime != null"> and create_time = #{startTime}</if>
|
||||
and in_speed is not null
|
||||
</where>
|
||||
</select>
|
||||
</mapper>
|
||||
Reference in New Issue
Block a user