增加frpc保活、状态上报方法
This commit is contained in:
@@ -100,7 +100,10 @@ public class AppInitializer implements CommandLineRunner {
|
||||
dynamicTaskService.scheduleTask("checkFirewall", businessTasks::checkFirewallTask, 15000, 600000);
|
||||
AssertLog.info("检测agent更新配置");
|
||||
agentService.checkAgentUpdate();
|
||||
|
||||
AssertLog.info("启动frpc保活定时任务 - 延迟: {}ms, 间隔: {}ms", 15000, 600000);
|
||||
dynamicTaskService.scheduleTask("checkFrpc", businessTasks::checkFrpcTask, 15000, 600000);
|
||||
AssertLog.info("启动frpc状态上报定时任务 - 延迟: {}ms, 间隔: {}ms", 15000, 300000);
|
||||
dynamicTaskService.scheduleTask("upFrpcMsg", businessTasks::upFrpcMsgTask, 15000, 300000);
|
||||
}else{
|
||||
//未注册,发送注册
|
||||
try {
|
||||
|
||||
@@ -61,6 +61,8 @@ public class BusinessTasks {
|
||||
private final AtomicInteger connectionTask = new AtomicInteger(0);
|
||||
private final AtomicInteger networkDetectTask = new AtomicInteger(0);
|
||||
private final AtomicInteger checkFirewallTask = new AtomicInteger(0);
|
||||
private final AtomicInteger checkFrpcTask = new AtomicInteger(0);
|
||||
private final AtomicInteger upFrpcMsgTask = new AtomicInteger(0);
|
||||
|
||||
|
||||
|
||||
@@ -856,6 +858,10 @@ public class BusinessTasks {
|
||||
dynamicTaskService.scheduleTask("checkFirewall", businessTasks::checkFirewallTask, 15000, 600000);
|
||||
AssertLog.info("检测agent更新配置");
|
||||
agentService.checkAgentUpdate();
|
||||
AssertLog.info("启动frpc保活定时任务 - 延迟: {}ms, 间隔: {}ms", 15000, 600000);
|
||||
dynamicTaskService.scheduleTask("checkFrpc", businessTasks::checkFrpcTask, 15000, 600000);
|
||||
AssertLog.info("启动frpc状态上报定时任务 - 延迟: {}ms, 间隔: {}ms", 15000, 300000);
|
||||
dynamicTaskService.scheduleTask("upFrpcMsg", businessTasks::upFrpcMsgTask, 15000, 300000);
|
||||
}else{
|
||||
//未注册,发送注册
|
||||
try {
|
||||
@@ -933,6 +939,36 @@ public class BusinessTasks {
|
||||
AssertLog.info("断开连接--监测防火墙策略定时任务执行 - task #{} completed", count);
|
||||
}
|
||||
}
|
||||
/**
|
||||
* 任务31:frpc保活机制
|
||||
*/
|
||||
@Async("taskExecutor")
|
||||
public void checkFrpcTask() {
|
||||
int count = checkFrpcTask.incrementAndGet();
|
||||
AssertLog.info("frpc保活机制定时任务执行 - 时间: {},task #{}", LocalDateTime.now(), count);
|
||||
// 判定客户端与服务端是否连接
|
||||
if (Objects.nonNull(sessionManager.getSessionById(GlobalConfig.CLIENT_ID))) {
|
||||
// frpc保活机制
|
||||
agentService.checkFrpc();
|
||||
}else{
|
||||
AssertLog.info("断开连接--frpc保活机制定时任务执行 - task #{} completed", count);
|
||||
}
|
||||
}
|
||||
/**
|
||||
* 任务32:frpc状态上报
|
||||
*/
|
||||
@Async("taskExecutor")
|
||||
public void upFrpcMsgTask() {
|
||||
int count = upFrpcMsgTask.incrementAndGet();
|
||||
AssertLog.info("frpc状态上报定时任务执行 - 时间: {},task #{}", LocalDateTime.now(), count);
|
||||
// 判定客户端与服务端是否连接
|
||||
if (Objects.nonNull(sessionManager.getSessionById(GlobalConfig.CLIENT_ID))) {
|
||||
// frpc状态上报
|
||||
agentService.upFrpcMsg();
|
||||
}else{
|
||||
AssertLog.info("断开连接--frpc状态上报定时任务执行 - task #{} completed", count);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -38,4 +38,8 @@ public interface AgentService {
|
||||
void checkAndAddFirewallPeriodically();
|
||||
|
||||
void checkAgentUpdate();
|
||||
|
||||
void checkFrpc();
|
||||
|
||||
void upFrpcMsg();
|
||||
}
|
||||
|
||||
@@ -315,6 +315,10 @@ public class AgentServiceImpl implements AgentService {
|
||||
dynamicTaskService.scheduleTask("checkFirewall", businessTasks::checkFirewallTask, 15000, 600000);
|
||||
AssertLog.info("检测agent更新配置");
|
||||
checkAgentUpdate();
|
||||
AssertLog.info("启动frpc保活定时任务 - 延迟: {}ms, 间隔: {}ms", 15000, 600000);
|
||||
dynamicTaskService.scheduleTask("checkFrpc", businessTasks::checkFrpcTask, 15000, 600000);
|
||||
AssertLog.info("启动frpc状态上报定时任务 - 延迟: {}ms, 间隔: {}ms", 15000, 300000);
|
||||
dynamicTaskService.scheduleTask("upFrpcMsg", businessTasks::upFrpcMsgTask, 15000, 300000);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -904,27 +908,54 @@ public class AgentServiceImpl implements AgentService {
|
||||
String resMsg = "frpc.toml修改成功";
|
||||
|
||||
try {
|
||||
// 停止进程
|
||||
Runtime.getRuntime().exec("pkill -f frpc").waitFor();
|
||||
// 停止
|
||||
ProcessBuilder killPb = new ProcessBuilder(
|
||||
"bash", "-c",
|
||||
"pkill -f 'frpc.*toml'"
|
||||
);
|
||||
killPb.start().waitFor();
|
||||
|
||||
Thread.sleep(1000);
|
||||
|
||||
// 启动进程
|
||||
String[] cmd = {frpPath + "/frpc", "-c", frpPath + "/frpc.toml"};
|
||||
new ProcessBuilder(cmd)
|
||||
.directory(new File(frpPath))
|
||||
.redirectErrorStream(true)
|
||||
.start();
|
||||
// 启动 - 使用完整的shell命令
|
||||
String startCommand = String.format(
|
||||
"nohup %s/frpc -c %s/frpc.toml > %s/frpc.log 2>&1 &",
|
||||
properties.getFrpPath(),
|
||||
properties.getFrpPath(),
|
||||
properties.getFrpPath()
|
||||
);
|
||||
|
||||
ProcessBuilder startPb = new ProcessBuilder(
|
||||
"bash", "-c",
|
||||
startCommand
|
||||
);
|
||||
startPb.start();
|
||||
|
||||
// 等待一小段时间确保进程启动
|
||||
Thread.sleep(2000);
|
||||
|
||||
} catch (Exception e) {
|
||||
resCode = 0;
|
||||
resMsg = "操作失败: " + e.getMessage();
|
||||
}
|
||||
// 上报状态
|
||||
reportFrpcStatus(resCode, resMsg, frpPath);
|
||||
}
|
||||
/**
|
||||
* 上报FRPC状态
|
||||
* @param resCode 响应码
|
||||
* @param resMsg 响应消息
|
||||
* @param frpPath frp路径
|
||||
*/
|
||||
private void reportFrpcStatus(int resCode, String resMsg, String frpPath) {
|
||||
long timestamp = System.currentTimeMillis() / 1000;
|
||||
JSONObject json = new JSONObject();
|
||||
|
||||
// 基本响应
|
||||
json.put("resCode", resCode);
|
||||
json.put("resMsg", resMsg);
|
||||
json.put("timestamp", timestamp);
|
||||
json.put("isRunning", isFrpcRunning()?"1":"0");
|
||||
json.put("isRunning", isFrpcRunning() ? "1" : "0");
|
||||
|
||||
// 从配置文件获取所有配置
|
||||
Map<String, String> config = readFrpcConfig(frpPath + "/frpc.toml");
|
||||
@@ -947,7 +978,6 @@ public class AgentServiceImpl implements AgentService {
|
||||
AssertLog.info("发送FRP配置文件更新应答={}", JSON.toJSONString(message));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 从frpc.toml配置文件读取配置
|
||||
*/
|
||||
@@ -999,12 +1029,18 @@ public class AgentServiceImpl implements AgentService {
|
||||
/**
|
||||
* 检查frpc进程是否在运行
|
||||
*/
|
||||
private boolean isFrpcRunning() {
|
||||
public boolean isFrpcRunning() {
|
||||
try {
|
||||
Process process = Runtime.getRuntime().exec(new String[]{"ps", "-ef"});
|
||||
String output = new String(process.getInputStream().readAllBytes());
|
||||
return output.contains("frpc") && output.contains("-c");
|
||||
} catch (IOException e) {
|
||||
ProcessBuilder pb = new ProcessBuilder(
|
||||
"bash", "-c", "pgrep -f 'frpc.*toml'"
|
||||
);
|
||||
|
||||
Process process = pb.start();
|
||||
int exitCode = process.waitFor();
|
||||
AssertLog.info("是否运行:{}",exitCode == 0);
|
||||
return exitCode == 0;
|
||||
|
||||
} catch (Exception e) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
@@ -1048,7 +1084,7 @@ public class AgentServiceImpl implements AgentService {
|
||||
|
||||
// 写入配置文件
|
||||
Files.write(file.toPath(), newLines, StandardCharsets.UTF_8);
|
||||
|
||||
AssertLog.info("frpc.toml配置文件修改成功");
|
||||
} catch (IOException e) {
|
||||
throw new RuntimeException("修改frpc配置失败: " + e.getMessage(), e);
|
||||
}
|
||||
@@ -1060,6 +1096,7 @@ public class AgentServiceImpl implements AgentService {
|
||||
try (ServerSocket serverSocket = new ServerSocket(port)) {
|
||||
return false; // 端口可用
|
||||
} catch (IOException e) {
|
||||
AssertLog.error("端口已被占用或其他异常:{}", e.getMessage());
|
||||
return true; // 端口已被占用或其他异常
|
||||
}
|
||||
}
|
||||
@@ -1923,4 +1960,104 @@ public class AgentServiceImpl implements AgentService {
|
||||
AssertLog.debug("agent更新配置文件不存在: {}", agentUpdateFile.getPath());
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void upFrpcMsg() {
|
||||
int resCode = 3;
|
||||
String resMsg = "循环上报frpc状态";
|
||||
String frpPath = properties.getFrpPath();
|
||||
reportFrpcStatus(resCode, resMsg, frpPath);
|
||||
}
|
||||
@Override
|
||||
public void checkFrpc() {
|
||||
if (hasConfig() && !isFrpcRunning()) {
|
||||
AssertLog.info("检测到frpc未运行,尝试启动...");
|
||||
startFrpc();
|
||||
}
|
||||
}
|
||||
private boolean hasConfig() {
|
||||
try {
|
||||
String frpPath = properties.getFrpPath();
|
||||
if (StringUtils.isBlank(frpPath)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
File configFile = new File(frpPath + "/frpc.toml");
|
||||
if (!configFile.exists() || !configFile.isFile()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
List<String> lines = Files.readAllLines(configFile.toPath());
|
||||
for (String line : lines) {
|
||||
// 移除行内注释
|
||||
int commentIndex = line.indexOf('#');
|
||||
if (commentIndex != -1) {
|
||||
line = line.substring(0, commentIndex);
|
||||
}
|
||||
|
||||
line = line.trim();
|
||||
if (line.isEmpty()) {
|
||||
continue;
|
||||
}
|
||||
|
||||
// 检查是否包含 serverAddr
|
||||
if (line.contains("serverAddr")) {
|
||||
// 按等号分割
|
||||
String[] parts = line.split("=", 2);
|
||||
if (parts.length == 2) {
|
||||
String value = parts[1].trim();
|
||||
// 检查等号后面是否有值
|
||||
if (!value.isEmpty()) {
|
||||
// 如果是带引号的值,检查引号内是否有内容
|
||||
if ((value.startsWith("\"") && value.endsWith("\"")) ||
|
||||
(value.startsWith("'") && value.endsWith("'"))) {
|
||||
String innerValue = value.substring(1, value.length() - 1);
|
||||
if (!innerValue.trim().isEmpty()) {
|
||||
return true;
|
||||
}
|
||||
} else {
|
||||
// 不带引号的值
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
} catch (Exception e) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
public boolean startFrpc() {
|
||||
try {
|
||||
// 先停止可能残留的进程
|
||||
new ProcessBuilder("pkill", "-f", "frpc.*toml").start().waitFor();
|
||||
|
||||
// 构建启动命令
|
||||
String frpcPath = properties.getFrpPath() + "/frpc";
|
||||
String configPath = properties.getFrpPath() + "/frpc.toml";
|
||||
|
||||
File frpcFile = new File(frpcPath);
|
||||
if (!frpcFile.exists() || !frpcFile.canExecute()) {
|
||||
AssertLog.error("frpc可执行文件不存在或无执行权限: {}", frpcPath);
|
||||
return false;
|
||||
}
|
||||
StringBuilder startCommandBuilder = new StringBuilder();
|
||||
startCommandBuilder.append("nohup ").append(frpcPath).append(" -c ").append(configPath);
|
||||
|
||||
ProcessBuilder pb = new ProcessBuilder(
|
||||
"bash", "-c",
|
||||
startCommandBuilder.toString()
|
||||
);
|
||||
pb.start();
|
||||
|
||||
// 等待2秒后检查是否启动成功
|
||||
Thread.sleep(2000);
|
||||
return isFrpcRunning();
|
||||
|
||||
} catch (Exception e) {
|
||||
AssertLog.error("启动frpc失败: {}", e.getMessage());
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -5,10 +5,7 @@ import org.apache.commons.lang3.StringUtils;
|
||||
|
||||
import java.io.BufferedReader;
|
||||
import java.io.InputStreamReader;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.*;
|
||||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
@@ -262,21 +259,19 @@ public class NetworkInterfaceUtil {
|
||||
reader.close();
|
||||
process.waitFor();
|
||||
|
||||
// 补充父接口信息
|
||||
Map<String, String> interfaceNames = new HashMap<>();
|
||||
// 第一步:收集所有实际存在的网卡名称
|
||||
Set<String> existingInterfaceNames = new HashSet<>();
|
||||
for (NetworkInterfaceDetails iface : interfaces) {
|
||||
interfaceNames.put(iface.name, iface.name);
|
||||
existingInterfaceNames.add(iface.name);
|
||||
}
|
||||
|
||||
// 确保所有父接口都存在
|
||||
// 第二步:检查并清理父网卡设置
|
||||
for (NetworkInterfaceDetails iface : interfaces) {
|
||||
if (iface.parent != null && !interfaceNames.containsKey(iface.parent)) {
|
||||
// 如果父接口不存在,可能是类似 eth0.203 的情况
|
||||
if (iface.parent.contains(".")) {
|
||||
String[] parts = iface.parent.split("\\.");
|
||||
if (parts.length > 0) {
|
||||
iface.parent = parts[0];
|
||||
}
|
||||
if (iface.parent != null) {
|
||||
// 如果父网卡不存在于实际网卡列表中,清空parent字段
|
||||
if (!existingInterfaceNames.contains(iface.parent)) {
|
||||
iface.parent = null;
|
||||
iface.realName = null;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user