fix 修复 windows DSL 模式:另一个程序正在使用此文件,进程无法访问。 问题

This commit is contained in:
bwcx_jzy 2022-12-01 09:10:25 +08:00
parent 84ddc27143
commit ccf2b66cb8
No known key found for this signature in database
GPG Key ID: 5E48E9372088B9E5
5 changed files with 229 additions and 162 deletions

View File

@ -5,16 +5,17 @@
### 🐣 新增功能
1. 【agent】新增 DSL 项目运行脚本环境变量配置(`run.start.scriptEnv`
2. 【agent】新增 DSL 项目自定义 `restart` 流程 `run.restart`
2. 【agent】新增 DSL 项目自定义 `restart` 流程 `run.restart`
### 🐞 解决BUG、优化功能
1. 【agent】修复 DSL 项目重启操作被偶发异常(自动)关闭问题
2. 【agent】优化 DSL 项目控制台日志输出格式
3. 优化日志监听器:控制台支持自动重定向、第一次启动项目自动重新 showlog
3. 【all】优化日志监听器:控制台支持自动重定向、第一次启动项目自动重新 showlog
4. 【server】节点超时时间配置为 0 失效问题
5. 【agent】修复进程列表在部分场景下进程号数字转换异常@易自玉)
6. 【agent】优化启动、停止、重启响应结果输出
7. 【agent】修复 windows DSL 模式:`另一个程序正在使用此文件,进程无法访问。` 问题
------

View File

@ -68,7 +68,6 @@ import java.util.*;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.TimeUnit;
import java.util.function.BiFunction;
import java.util.function.Function;
import java.util.jar.Attributes;
import java.util.jar.JarFile;
import java.util.jar.Manifest;
@ -541,7 +540,7 @@ public abstract class AbstractProjectCommander {
.map(s -> {
int pid = ProjectCommanderUtil.parsePid(s);
return CommandOpResult.of(pid > 0, s);
}).orElse(null);
}).orElseGet(() -> CommandOpResult.of(false, STOP_TAG));
} else {
String tag = javaCopyItem == null ? nodeProjectInfoModel.getId() : javaCopyItem.getTagId();

View File

@ -25,16 +25,20 @@ package io.jpom.script;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.date.DatePattern;
import cn.hutool.core.date.DateTime;
import cn.hutool.core.date.DateUnit;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.io.FileUtil;
import cn.hutool.core.io.IoUtil;
import cn.hutool.core.io.LineHandler;
import cn.hutool.core.thread.ThreadUtil;
import cn.hutool.core.util.IdUtil;
import cn.hutool.core.util.StrUtil;
import cn.jiangzeyin.common.spring.SpringUtil;
import io.jpom.model.data.DslYmlDto;
import io.jpom.model.data.NodeProjectInfoModel;
import io.jpom.model.data.NodeScriptModel;
import io.jpom.service.script.NodeScriptServer;
import io.jpom.system.ConfigBean;
import io.jpom.system.ExtConfigBean;
import io.jpom.util.CommandUtil;
import lombok.Setter;
@ -59,6 +63,7 @@ public class DslScriptBuilder extends BaseRunScript implements Runnable {
private final String args;
private String action;
private File scriptFile;
private boolean autoDelete;
private Map<String, String> environment;
private DslScriptBuilder(String action, Map<String, String> environment, String args, String log) {
@ -166,6 +171,18 @@ public class DslScriptBuilder extends BaseRunScript implements Runnable {
}
@Override
public void close() {
super.close();
//
if (autoDelete) {
try {
FileUtil.del(this.scriptFile);
} catch (Exception ignored) {
}
}
}
/**
* 异步执行
*
@ -195,23 +212,33 @@ public class DslScriptBuilder extends BaseRunScript implements Runnable {
NodeScriptServer nodeScriptServer = SpringUtil.getBean(NodeScriptServer.class);
String scriptId = scriptProcess.getScriptId();
NodeScriptModel item = nodeScriptServer.getItem(scriptId);
Map<String, String> environment = DslScriptBuilder.environment(nodeProjectInfoModel);
File scriptFile;
boolean autoDelete = false;
if (item == null) {
scriptFile = FileUtil.file(nodeProjectInfoModel.allLib(), scriptId);
Assert.state(FileUtil.isFile(scriptFile), "脚本模版不存在:" + scriptProcess.getScriptId());
} else {
scriptFile = DslScriptBuilder.initScriptFile(item, nodeProjectInfoModel);
scriptFile = DslScriptBuilder.initScriptFile(item, environment);
autoDelete = true;
}
DslScriptBuilder builder = new DslScriptBuilder(action, scriptProcess.getScriptEnv(), scriptProcess.getScriptArgs(), log);
builder.putEnvironment(DslScriptBuilder.environment(nodeProjectInfoModel));
builder.putEnvironment(environment);
builder.setScriptFile(scriptFile);
builder.setAutoDelete(autoDelete);
return builder;
}
private static File initScriptFile(NodeScriptModel scriptModel, NodeProjectInfoModel nodeProjectInfoModel) {
String id = nodeProjectInfoModel.getId();
File scriptFile = scriptModel.scriptFile("_" + id);
Map<String, String> dslEnv = environment(nodeProjectInfoModel);
/**
* 创建脚本文件
*
* @param scriptModel 脚本对象
* @param dslEnv 环境变量
* @return file
*/
private static File initScriptFile(NodeScriptModel scriptModel, Map<String, String> dslEnv) {
String dataPath = ConfigBean.getInstance().getDataPath();
File scriptFile = FileUtil.file(dataPath, ConfigBean.SCRIPT_RUN_CACHE_DIRECTORY, StrUtil.format("{}.{}", IdUtil.fastSimpleUUID(), CommandUtil.SUFFIX));
// 替换内容
String context = scriptModel.getContext();
for (Map.Entry<String, String> envEntry : dslEnv.entrySet()) {
@ -222,6 +249,33 @@ public class DslScriptBuilder extends BaseRunScript implements Runnable {
return scriptFile;
}
/**
* 清理 脚本文件执行缓存
*/
public static void clearRunScript() {
String dataPath = ConfigBean.getInstance().getDataPath();
File scriptFile = FileUtil.file(dataPath, ConfigBean.SCRIPT_RUN_CACHE_DIRECTORY);
if (!FileUtil.isDirectory(scriptFile)) {
return;
}
File[] files = scriptFile.listFiles(pathname -> {
Date lastModifiedTime = FileUtil.lastModifiedTime(pathname);
DateTime now = DateTime.now();
long between = DateUtil.between(lastModifiedTime, now, DateUnit.HOUR);
// 文件大于一个小时才能被删除
return between > 1;
});
if (files == null) {
return;
}
for (File file : files) {
try {
FileUtil.del(file);
} catch (Exception ignored) {
}
}
}
private static Map<String, String> environment(NodeProjectInfoModel nodeProjectInfoModel) {
Map<String, String> dslEnv = new HashMap<>(10);
dslEnv.put("PROJECT_ID", nodeProjectInfoModel.getId());

View File

@ -35,6 +35,7 @@ import io.jpom.common.RemoteVersion;
import io.jpom.common.commander.AbstractProjectCommander;
import io.jpom.cron.CronUtils;
import io.jpom.model.data.NodeProjectInfoModel;
import io.jpom.script.DslScriptBuilder;
import io.jpom.service.manage.ProjectInfoService;
import io.jpom.system.AgentExtConfigBean;
import lombok.extern.slf4j.Slf4j;
@ -121,8 +122,16 @@ public class AutoBackLog {
private static void systemMonitor() {
// 开启检测调度
ThreadUtil.execute(() -> {
CronUtils.upsert("system_monitor", "0 0 0,12 * * ?", RemoteVersion::loadRemoteInfo);
RemoteVersion.loadRemoteInfo();
// 定时任务
CronUtils.upsert("system_monitor", "0 0 0,12 * * ?", AutoBackLog::systemTask);
systemTask();
});
}
private static void systemTask() {
// 启动加载
RemoteVersion.loadRemoteInfo();
// 清空脚本缓存
DslScriptBuilder.clearRunScript();
}
}

View File

@ -58,6 +58,10 @@ public class ConfigBean {
* 脚本模板存放路径
*/
public static final String SCRIPT_DIRECTORY = "script";
/**
* 脚本默认运行缓存执行文件路径考虑 windows 文件被占用情况
*/
public static final String SCRIPT_RUN_CACHE_DIRECTORY = "script_run_cache";
/**
* 授权信息
*/