mtr监控策略初版
This commit is contained in:
@@ -9,9 +9,9 @@
|
|||||||
<relativePath/> <!-- lookup parent from repository -->
|
<relativePath/> <!-- lookup parent from repository -->
|
||||||
</parent>
|
</parent>
|
||||||
<groupId>com.tongran.agent</groupId>
|
<groupId>com.tongran.agent</groupId>
|
||||||
<artifactId>tr-agent-client</artifactId>
|
<artifactId>tr-mtragent-client</artifactId>
|
||||||
<version>0.0.1-SNAPSHOT</version>
|
<version>0.0.1-SNAPSHOT</version>
|
||||||
<name>tr-agent-client</name>
|
<name>tr-mtragent-client</name>
|
||||||
<description>tr-agent-client</description>
|
<description>tr-agent-client</description>
|
||||||
|
|
||||||
<properties>
|
<properties>
|
||||||
|
|||||||
@@ -56,6 +56,7 @@ public class GlobalConfig {
|
|||||||
public static long SCRIPT_TIME = 0L;
|
public static long SCRIPT_TIME = 0L;
|
||||||
public static long VERSION_TIME = 0L;
|
public static long VERSION_TIME = 0L;
|
||||||
public static long ROUTE_TIME = 0L;
|
public static long ROUTE_TIME = 0L;
|
||||||
|
public static String MTRPOLICYMSG = "";
|
||||||
/**
|
/**
|
||||||
* 采集标识
|
* 采集标识
|
||||||
*/
|
*/
|
||||||
|
|||||||
@@ -67,6 +67,8 @@ public enum MsgEnum {
|
|||||||
|
|
||||||
Agent版本更新应答("AGENT_VERSION_UPDATE_RSP"),
|
Agent版本更新应答("AGENT_VERSION_UPDATE_RSP"),
|
||||||
|
|
||||||
|
MTR探测上报("MTR_DETECT"),
|
||||||
|
|
||||||
多网IP探测上报("NETWORK_DETECT");
|
多网IP探测上报("NETWORK_DETECT");
|
||||||
|
|
||||||
private String value;
|
private String value;
|
||||||
|
|||||||
@@ -0,0 +1,45 @@
|
|||||||
|
package com.tongran.agent.client.core.eo;
|
||||||
|
|
||||||
|
import com.fasterxml.jackson.annotation.JsonFormat;
|
||||||
|
import lombok.Data;
|
||||||
|
|
||||||
|
import java.util.Date;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* mtr策略信息
|
||||||
|
*/
|
||||||
|
@Data
|
||||||
|
public class MtrPolicyConfigEO {
|
||||||
|
private static final long serialVersionUID = 1L;
|
||||||
|
|
||||||
|
/** 主键ID */
|
||||||
|
private Long id;
|
||||||
|
|
||||||
|
/** 策略名称 */
|
||||||
|
private String policyName;
|
||||||
|
|
||||||
|
/** 优先级 */
|
||||||
|
private Long priority;
|
||||||
|
|
||||||
|
/** MTR客户端ID */
|
||||||
|
private String mtrClientId;
|
||||||
|
|
||||||
|
/** 服务器集合(换行符分割) */
|
||||||
|
private String serverGroup;
|
||||||
|
/** 探测目标ip集合 */
|
||||||
|
private String serveripGroup;
|
||||||
|
|
||||||
|
/** 是否探测(0-否,1-是) */
|
||||||
|
private Long probeFlag;
|
||||||
|
|
||||||
|
/** 开始时间 */
|
||||||
|
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
|
||||||
|
private Date startTime;
|
||||||
|
|
||||||
|
/** 结束时间 */
|
||||||
|
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
|
||||||
|
private Date endTime;
|
||||||
|
|
||||||
|
/** 探测频率(秒) */
|
||||||
|
private Long probeFrequency;
|
||||||
|
}
|
||||||
@@ -0,0 +1,16 @@
|
|||||||
|
package com.tongran.agent.client.core.vo;
|
||||||
|
|
||||||
|
import lombok.Data;
|
||||||
|
|
||||||
|
import java.util.Date;
|
||||||
|
|
||||||
|
@Data
|
||||||
|
public class MtrVO {
|
||||||
|
private String targetIp; // 目标IP
|
||||||
|
private Long policyId; // 策略ID
|
||||||
|
private double firstLossPercent; // 第一次探测丢包率
|
||||||
|
private double finalLossPercent; // 最终丢包率
|
||||||
|
private long timestamp; // 探测时间戳
|
||||||
|
private boolean hasRetry; // 是否重试
|
||||||
|
private String errorMsg; // 错误信息
|
||||||
|
}
|
||||||
@@ -7,6 +7,7 @@ import com.alibaba.fastjson2.JSONObject;
|
|||||||
import com.tongran.agent.client.core.config.ApplicationProperties;
|
import com.tongran.agent.client.core.config.ApplicationProperties;
|
||||||
import com.tongran.agent.client.core.config.GlobalConfig;
|
import com.tongran.agent.client.core.config.GlobalConfig;
|
||||||
import com.tongran.agent.client.core.enums.MsgEnum;
|
import com.tongran.agent.client.core.enums.MsgEnum;
|
||||||
|
import com.tongran.agent.client.core.eo.MtrPolicyConfigEO;
|
||||||
import com.tongran.agent.client.core.session.SessionManager;
|
import com.tongran.agent.client.core.session.SessionManager;
|
||||||
import com.tongran.agent.client.core.vo.*;
|
import com.tongran.agent.client.core.vo.*;
|
||||||
import com.tongran.agent.client.netty.MultiTargetNettyClient;
|
import com.tongran.agent.client.netty.MultiTargetNettyClient;
|
||||||
@@ -59,6 +60,7 @@ public class BusinessTasks {
|
|||||||
private final AtomicInteger registerTask = new AtomicInteger(0);
|
private final AtomicInteger registerTask = new AtomicInteger(0);
|
||||||
private final AtomicInteger connectionTask = new AtomicInteger(0);
|
private final AtomicInteger connectionTask = new AtomicInteger(0);
|
||||||
private final AtomicInteger networkDetectTask = new AtomicInteger(0);
|
private final AtomicInteger networkDetectTask = new AtomicInteger(0);
|
||||||
|
private final AtomicInteger mtrTask = new AtomicInteger(0);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@@ -108,6 +110,9 @@ public class BusinessTasks {
|
|||||||
@Resource
|
@Resource
|
||||||
private AgentService agentService;
|
private AgentService agentService;
|
||||||
|
|
||||||
|
@Resource
|
||||||
|
private MtrService mtrService;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 任务1:心跳上报任务
|
* 任务1:心跳上报任务
|
||||||
*/
|
*/
|
||||||
@@ -900,6 +905,55 @@ public class BusinessTasks {
|
|||||||
AssertLog.info("发送多网IP探测定时任务执行 - task #{} completed", count);
|
AssertLog.info("发送多网IP探测定时任务执行 - task #{} completed", count);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 任务30:MTR网络探测任务
|
||||||
|
*/
|
||||||
|
@Async("taskExecutor")
|
||||||
|
public void mtrTask() {
|
||||||
|
long timestamp = AgentUtil.roundMinutes(); // 使用5分钟整点时间
|
||||||
|
int count = mtrTask.incrementAndGet();
|
||||||
|
AssertLog.info("MTR网络探测定时任务执行 - 时间: {},task #{}", LocalDateTime.now(), count);
|
||||||
|
|
||||||
|
try {
|
||||||
|
// 检查当前是否有有效的MTR策略
|
||||||
|
if (StringUtils.isBlank(GlobalConfig.MTRPOLICYMSG)) {
|
||||||
|
AssertLog.info("没有MTR策略配置,跳过本次执行");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 解析策略
|
||||||
|
List<MtrPolicyConfigEO> mtrPolicyConfigEOList = JSON.parseArray(GlobalConfig.MTRPOLICYMSG, MtrPolicyConfigEO.class);
|
||||||
|
if (CollectionUtil.isEmpty(mtrPolicyConfigEOList)) {
|
||||||
|
AssertLog.info("MTR策略列表为空,跳过本次执行");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 判定客户端与服务端是否连接
|
||||||
|
if (Objects.nonNull(sessionManager.getSessionById(GlobalConfig.CLIENT_ID))) {
|
||||||
|
// 执行MTR探测并获取结果
|
||||||
|
String data = "";
|
||||||
|
List<MtrVO> list = mtrService.mtrList(timestamp, mtrPolicyConfigEOList);
|
||||||
|
if (CollectionUtil.isNotEmpty(list)) {
|
||||||
|
data = JSONArray.toJSONString(list);
|
||||||
|
|
||||||
|
// 发送MTR探测结果
|
||||||
|
Message message = Message.builder()
|
||||||
|
.clientId(GlobalConfig.CLIENT_ID)
|
||||||
|
.dataType(MsgEnum.MTR探测上报.getValue())
|
||||||
|
.data(data)
|
||||||
|
.build();
|
||||||
|
sessionManager.writeAndFlush(sessionManager.getSessionById(GlobalConfig.CLIENT_ID).getChannel(), message);
|
||||||
|
AssertLog.info("发送MTR探测信息包,结果数量: {}", list.size());
|
||||||
|
} else {
|
||||||
|
AssertLog.info("本次MTR探测无有效结果");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} catch (Exception e) {
|
||||||
|
AssertLog.error("MTR定时任务执行异常", e);
|
||||||
|
}
|
||||||
|
|
||||||
|
AssertLog.info("MTR网络探测定时任务执行 - task #{} completed", count);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,10 @@
|
|||||||
|
package com.tongran.agent.client.service;
|
||||||
|
|
||||||
|
import com.tongran.agent.client.core.eo.MtrPolicyConfigEO;
|
||||||
|
import com.tongran.agent.client.core.vo.MtrVO;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
public interface MtrService {
|
||||||
|
List<MtrVO> mtrList(long timestamp, List<MtrPolicyConfigEO> mtrPolicyConfigEOList);
|
||||||
|
}
|
||||||
@@ -9,8 +9,10 @@ import com.tongran.agent.client.core.config.GlobalConfig;
|
|||||||
import com.tongran.agent.client.core.enums.MsgEnum;
|
import com.tongran.agent.client.core.enums.MsgEnum;
|
||||||
import com.tongran.agent.client.core.eo.AgentVersionUpdateEO;
|
import com.tongran.agent.client.core.eo.AgentVersionUpdateEO;
|
||||||
import com.tongran.agent.client.core.eo.CollectEO;
|
import com.tongran.agent.client.core.eo.CollectEO;
|
||||||
|
import com.tongran.agent.client.core.eo.MtrPolicyConfigEO;
|
||||||
import com.tongran.agent.client.core.eo.ScriptPolicyEO;
|
import com.tongran.agent.client.core.eo.ScriptPolicyEO;
|
||||||
import com.tongran.agent.client.core.session.SessionManager;
|
import com.tongran.agent.client.core.session.SessionManager;
|
||||||
|
import com.tongran.agent.client.core.vo.MtrVO;
|
||||||
import com.tongran.agent.client.netty.MultiTargetNettyClient;
|
import com.tongran.agent.client.netty.MultiTargetNettyClient;
|
||||||
import com.tongran.agent.client.netty.config.AgentNettyConfig;
|
import com.tongran.agent.client.netty.config.AgentNettyConfig;
|
||||||
import com.tongran.agent.client.netty.model.Message;
|
import com.tongran.agent.client.netty.model.Message;
|
||||||
@@ -35,6 +37,9 @@ import java.time.LocalDateTime;
|
|||||||
import java.util.*;
|
import java.util.*;
|
||||||
import java.util.concurrent.CompletableFuture;
|
import java.util.concurrent.CompletableFuture;
|
||||||
import java.util.concurrent.TimeUnit;
|
import java.util.concurrent.TimeUnit;
|
||||||
|
import java.util.concurrent.TimeoutException;
|
||||||
|
import java.util.regex.Matcher;
|
||||||
|
import java.util.regex.Pattern;
|
||||||
import java.util.stream.Collectors;
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
@Service
|
@Service
|
||||||
@@ -825,11 +830,73 @@ public class AgentServiceImpl implements AgentService {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
if(jsonObject.containsKey("mtrPolicys")){
|
||||||
|
String mtrPolicys = jsonObject.getString("mtrPolicys");
|
||||||
|
if(!mtrPolicys.equals(GlobalConfig.MTRPOLICYMSG)){
|
||||||
|
GlobalConfig.MTRPOLICYMSG = mtrPolicys;
|
||||||
|
List<MtrPolicyConfigEO> mtrPolicyConfigEOList = JSON.parseArray(mtrPolicys, MtrPolicyConfigEO.class);
|
||||||
|
try {
|
||||||
|
if (CollectionUtil.isEmpty(mtrPolicyConfigEOList)) {
|
||||||
|
// 如果没有策略,取消定时任务
|
||||||
|
dynamicTaskService.cancelTask("mtrTask");
|
||||||
|
AssertLog.info("MTR策略为空,取消MTR定时任务");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 检查是否有有效的策略(在时间范围内的策略)
|
||||||
|
boolean hasValidPolicy = false;
|
||||||
|
long currentTimestamp = System.currentTimeMillis() / 1000;
|
||||||
|
|
||||||
|
for (MtrPolicyConfigEO policy : mtrPolicyConfigEOList) {
|
||||||
|
if (isPolicyTimeValid(policy, currentTimestamp)) {
|
||||||
|
hasValidPolicy = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!hasValidPolicy) {
|
||||||
|
// 没有有效策略,取消定时任务
|
||||||
|
dynamicTaskService.cancelTask("mtrTask");
|
||||||
|
AssertLog.info("没有有效的MTR策略,取消MTR定时任务");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 计算下一个5分钟整点的延迟时间
|
||||||
|
long milli = AgentUtil.millisecondsToNext5Minute();
|
||||||
|
|
||||||
|
// 启动或更新定时任务
|
||||||
|
dynamicTaskService.scheduleTask("mtrTask",
|
||||||
|
businessTasks::mtrTask, milli, 300000L); // 5分钟间隔
|
||||||
|
|
||||||
|
AssertLog.info("MTR定时任务已启动/更新,延迟: {}ms, 间隔: 300000ms", milli);
|
||||||
|
|
||||||
|
} catch (Exception e) {
|
||||||
|
AssertLog.error("启动MTR定时任务异常", e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
/**
|
||||||
|
* 检查策略时间是否有效
|
||||||
|
*/
|
||||||
|
private boolean isPolicyTimeValid(MtrPolicyConfigEO policy, long currentTimestamp) {
|
||||||
|
try {
|
||||||
|
Date currentTime = new Date(currentTimestamp * 1000);
|
||||||
|
Date startTime = policy.getStartTime();
|
||||||
|
Date endTime = policy.getEndTime();
|
||||||
|
|
||||||
|
// 开始时间为空表示立即开始
|
||||||
|
boolean startValid = startTime == null || !currentTime.before(startTime);
|
||||||
|
// 结束时间为空表示永不过期
|
||||||
|
boolean endValid = endTime == null || !currentTime.after(endTime);
|
||||||
|
|
||||||
|
return startValid && endValid;
|
||||||
|
} catch (Exception e) {
|
||||||
|
AssertLog.error("检查策略时间有效性异常", e);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
@Override
|
@Override
|
||||||
public void checkTrAgent() {
|
public void checkTrAgent() {
|
||||||
String CRON_FILE_PATH = properties.getScriptPath()+"/tr_live.cron";
|
String CRON_FILE_PATH = properties.getScriptPath()+"/tr_live.cron";
|
||||||
@@ -904,7 +971,7 @@ public class AgentServiceImpl implements AgentService {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean connection() {
|
public boolean connection() {
|
||||||
String clientId = MachineFingerprint.getHardwareFingerprint();
|
String clientId = "MTR" + MachineFingerprint.getHardwareFingerprint();
|
||||||
//初始化SN信息
|
//初始化SN信息
|
||||||
GlobalConfig.DEVICE_SN = AgentUtil.getDeviceSN();
|
GlobalConfig.DEVICE_SN = AgentUtil.getDeviceSN();
|
||||||
//检查外置目录是否存在
|
//检查外置目录是否存在
|
||||||
|
|||||||
@@ -0,0 +1,213 @@
|
|||||||
|
package com.tongran.agent.client.service.impl;
|
||||||
|
|
||||||
|
import cn.hutool.core.collection.CollectionUtil;
|
||||||
|
import com.alibaba.fastjson2.JSON;
|
||||||
|
import com.alibaba.fastjson2.JSONObject;
|
||||||
|
import com.tongran.agent.client.core.eo.MtrPolicyConfigEO;
|
||||||
|
import com.tongran.agent.client.core.vo.MtrVO;
|
||||||
|
import com.tongran.agent.client.core.vo.NetVO;
|
||||||
|
import com.tongran.agent.client.service.MtrService;
|
||||||
|
import com.tongran.agent.client.utils.AgentUtil;
|
||||||
|
import com.tongran.agent.client.utils.AssertLog;
|
||||||
|
import org.springframework.stereotype.Service;
|
||||||
|
import oshi.SystemInfo;
|
||||||
|
import oshi.hardware.HardwareAbstractionLayer;
|
||||||
|
import oshi.hardware.NetworkIF;
|
||||||
|
import oshi.util.FormatUtil;
|
||||||
|
|
||||||
|
import java.io.BufferedReader;
|
||||||
|
import java.io.InputStreamReader;
|
||||||
|
import java.util.*;
|
||||||
|
import java.util.concurrent.CompletableFuture;
|
||||||
|
import java.util.concurrent.TimeUnit;
|
||||||
|
import java.util.regex.Matcher;
|
||||||
|
import java.util.regex.Pattern;
|
||||||
|
|
||||||
|
@Service
|
||||||
|
public class MtrServiceImpl implements MtrService {
|
||||||
|
/**
|
||||||
|
* 执行MTR探测列表 - 异步版本
|
||||||
|
*/
|
||||||
|
public List<MtrVO> mtrList(long timestamp, List<MtrPolicyConfigEO> mtrPolicyConfigEOList) {
|
||||||
|
List<CompletableFuture<MtrVO>> futures = new ArrayList<>();
|
||||||
|
List<MtrVO> mtrResults = new ArrayList<>();
|
||||||
|
|
||||||
|
try {
|
||||||
|
if (CollectionUtil.isEmpty(mtrPolicyConfigEOList)) {
|
||||||
|
return mtrResults;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 为每个IP创建异步任务
|
||||||
|
for (MtrPolicyConfigEO policy : mtrPolicyConfigEOList) {
|
||||||
|
if (!isPolicyTimeValid(policy, timestamp)) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
String[] targetIps = policy.getServeripGroup().split(";");
|
||||||
|
for (String targetIp : targetIps) {
|
||||||
|
String ip = targetIp.trim();
|
||||||
|
if (!ip.isEmpty()) {
|
||||||
|
// 异步执行每个IP的探测
|
||||||
|
CompletableFuture<MtrVO> future = CompletableFuture.supplyAsync(() ->
|
||||||
|
executeSingleMtrProbe(ip, policy, timestamp)
|
||||||
|
);
|
||||||
|
futures.add(future);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 等待所有任务完成
|
||||||
|
CompletableFuture<Void> allFutures = CompletableFuture.allOf(
|
||||||
|
futures.toArray(new CompletableFuture[0])
|
||||||
|
);
|
||||||
|
|
||||||
|
// 获取所有结果(设置超时时间,比如2分钟)
|
||||||
|
allFutures.get(2, TimeUnit.MINUTES);
|
||||||
|
|
||||||
|
for (CompletableFuture<MtrVO> future : futures) {
|
||||||
|
MtrVO result = future.get();
|
||||||
|
if (result != null) {
|
||||||
|
mtrResults.add(result);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
} catch (Exception e) {
|
||||||
|
AssertLog.error("MTR异步探测异常", e);
|
||||||
|
}
|
||||||
|
|
||||||
|
return mtrResults;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 检查策略时间是否有效
|
||||||
|
*/
|
||||||
|
private boolean isPolicyTimeValid(MtrPolicyConfigEO policy, long currentTimestamp) {
|
||||||
|
try {
|
||||||
|
// 将时间戳转换为Date对象进行比较
|
||||||
|
Date currentTime = new Date(currentTimestamp * 1000);
|
||||||
|
Date startTime = policy.getStartTime();
|
||||||
|
Date endTime = policy.getEndTime();
|
||||||
|
|
||||||
|
// 开始时间为空表示立即开始
|
||||||
|
boolean startValid = startTime == null || !currentTime.before(startTime);
|
||||||
|
// 结束时间为空表示永不过期
|
||||||
|
boolean endValid = endTime == null || !currentTime.after(endTime);
|
||||||
|
|
||||||
|
return startValid && endValid;
|
||||||
|
} catch (Exception e) {
|
||||||
|
AssertLog.error("检查策略时间有效性异常", e);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 执行单个IP的MTR探测
|
||||||
|
*/
|
||||||
|
private MtrVO executeSingleMtrProbe(String targetIp, MtrPolicyConfigEO policy, long timestamp) {
|
||||||
|
MtrVO mtrVO = new MtrVO();
|
||||||
|
mtrVO.setTargetIp(targetIp);
|
||||||
|
mtrVO.setPolicyId(policy.getId());
|
||||||
|
mtrVO.setTimestamp(timestamp);
|
||||||
|
|
||||||
|
try {
|
||||||
|
// 第一次MTR探测
|
||||||
|
double firstLossPercent = executeMtrCommand(targetIp);
|
||||||
|
mtrVO.setFirstLossPercent(firstLossPercent);
|
||||||
|
|
||||||
|
// 如果丢包率超过5%,30秒后重试
|
||||||
|
if (firstLossPercent > 5.0) {
|
||||||
|
AssertLog.info("目标IP {} 丢包率 {}% > 5%,30秒后重试探测", targetIp, firstLossPercent);
|
||||||
|
|
||||||
|
// 等待30秒
|
||||||
|
Thread.sleep(30000);
|
||||||
|
|
||||||
|
// 第二次MTR探测
|
||||||
|
double secondLossPercent = executeMtrCommand(targetIp);
|
||||||
|
mtrVO.setFinalLossPercent(secondLossPercent);
|
||||||
|
mtrVO.setHasRetry(true);
|
||||||
|
|
||||||
|
AssertLog.info("目标IP {} 重试探测完成,最终丢包率: {}%", targetIp, secondLossPercent);
|
||||||
|
} else {
|
||||||
|
mtrVO.setFinalLossPercent(firstLossPercent);
|
||||||
|
mtrVO.setHasRetry(false);
|
||||||
|
AssertLog.info("目标IP {} 丢包率 {}%,无需重试", targetIp, firstLossPercent);
|
||||||
|
}
|
||||||
|
|
||||||
|
return mtrVO;
|
||||||
|
|
||||||
|
} catch (Exception e) {
|
||||||
|
AssertLog.error("MTR探测异常 - IP: {}", targetIp, e);
|
||||||
|
mtrVO.setFinalLossPercent(-1.0); // -1表示探测失败
|
||||||
|
mtrVO.setErrorMsg(e.getMessage());
|
||||||
|
return mtrVO;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 执行mtr -r命令并解析结果
|
||||||
|
*/
|
||||||
|
private double executeMtrCommand(String targetIp) {
|
||||||
|
Process process = null;
|
||||||
|
try {
|
||||||
|
// 执行mtr -r -c 10命令
|
||||||
|
ProcessBuilder processBuilder = new ProcessBuilder("mtr", "-r", "-c", "10", targetIp);
|
||||||
|
process = processBuilder.start();
|
||||||
|
|
||||||
|
// 读取命令输出
|
||||||
|
BufferedReader reader = new BufferedReader(new InputStreamReader(process.getInputStream()));
|
||||||
|
String line;
|
||||||
|
String lastValidLine = null;
|
||||||
|
|
||||||
|
while ((line = reader.readLine()) != null) {
|
||||||
|
// 跳过标题行,记录最后一条有效数据行
|
||||||
|
if (!line.trim().isEmpty() &&
|
||||||
|
!line.startsWith("Start:") &&
|
||||||
|
!line.startsWith("HOST:") &&
|
||||||
|
Character.isDigit(line.trim().charAt(0))) {
|
||||||
|
lastValidLine = line;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 等待命令执行完成
|
||||||
|
boolean finished = process.waitFor(2, TimeUnit.MINUTES);
|
||||||
|
if (!finished) {
|
||||||
|
process.destroy();
|
||||||
|
throw new RuntimeException("MTR命令执行超时");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (lastValidLine == null) {
|
||||||
|
throw new RuntimeException("MTR命令无有效输出");
|
||||||
|
}
|
||||||
|
|
||||||
|
// 解析丢包率
|
||||||
|
return parseLossPercentFromMtrOutput(lastValidLine);
|
||||||
|
|
||||||
|
} catch (Exception e) {
|
||||||
|
throw new RuntimeException("MTR命令执行异常: " + e.getMessage());
|
||||||
|
} finally {
|
||||||
|
if (process != null) {
|
||||||
|
process.destroy();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 从MTR输出中解析丢包率
|
||||||
|
*/
|
||||||
|
private double parseLossPercentFromMtrOutput(String mtrOutputLine) {
|
||||||
|
try {
|
||||||
|
// 使用正则表达式匹配Loss%列
|
||||||
|
Pattern pattern = Pattern.compile("(\\d+\\.?\\d*)%");
|
||||||
|
Matcher matcher = pattern.matcher(mtrOutputLine);
|
||||||
|
|
||||||
|
if (matcher.find()) {
|
||||||
|
return Double.parseDouble(matcher.group(1));
|
||||||
|
}
|
||||||
|
|
||||||
|
throw new RuntimeException("未找到Loss%数据: " + mtrOutputLine);
|
||||||
|
} catch (Exception e) {
|
||||||
|
throw new RuntimeException("解析Loss%失败: " + e.getMessage());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -17,7 +17,7 @@ logging:
|
|||||||
netty:
|
netty:
|
||||||
server:
|
server:
|
||||||
host: 120.211.95.173
|
host: 120.211.95.173
|
||||||
port: 6620
|
port: 6610
|
||||||
client:
|
client:
|
||||||
client-id: client-001
|
client-id: client-001
|
||||||
reconnect-interval: 5
|
reconnect-interval: 5
|
||||||
|
|||||||
@@ -5,8 +5,8 @@ spring:
|
|||||||
pathmatch:
|
pathmatch:
|
||||||
matching-strategy: ant_path_matcher
|
matching-strategy: ant_path_matcher
|
||||||
application:
|
application:
|
||||||
name: tr-agent-client
|
name: tr-mtragent-client
|
||||||
version: 1.1.4
|
version: 1.0.0
|
||||||
conf-path: /usr/local/tongran/conf
|
conf-path: /usr/local/tongran/conf
|
||||||
script-path: /usr/local/tongran/sbin
|
script-path: /usr/local/tongran/sbin
|
||||||
tmp-path: /usr/local/tongran/tmp
|
tmp-path: /usr/local/tongran/tmp
|
||||||
|
|||||||
Reference in New Issue
Block a user