[测评系统]--测评系统核心代码库
wzp
2025-07-16 6cd5fefaf5f5f87572765b7d32cfa644541275cd
src/main/java/com/ots/project/tool/PdfDockerUtil.java
@@ -36,7 +36,7 @@
    /**
     * 任务超时时间(秒)
     */
    private static final int TASK_TIMEOUT_SECONDS = 300; // 5分钟
    private static final int TASK_TIMEOUT_SECONDS = 60; // 1分钟
    
    /**
     * 私有构造函数,防止外部实例化
@@ -82,11 +82,11 @@
            // 2. 生成唯一容器名称
            String containerName = CONTAINER_NAME_PREFIX + System.currentTimeMillis();
            
            // 3. 清理旧容器
            // 3. 轻量级清理旧容器(可选,如果不需要可以注释掉)
            cleanupOldContainers();
            
            // 4. 构建Docker命令
            String command = MessageFormat.format(docx2pdfPath, profile, fileName);
            // 4. 构建Docker命令(确保包含容器名称)
            String command = buildDockerCommand(docx2pdfPath, profile, fileName, containerName);
            log.info("docker执行命令:{}", command);
            
            // 5. 执行Docker命令(带超时)
@@ -130,6 +130,40 @@
    }
    
    /**
     * 构建Docker命令,确保包含容器名称
     * @param docx2pdfPath docker命令模板路径
     * @param profile 配置文件路径
     * @param fileName 文件名
     * @param containerName 容器名称
     * @return 完整的Docker命令
     */
    private String buildDockerCommand(String docx2pdfPath, String profile, String fileName, String containerName) {
        // 如果命令模板中已经包含 --name 参数,则直接使用
        if (docx2pdfPath.contains("--name")) {
            return MessageFormat.format(docx2pdfPath, profile, fileName);
        }
        // 如果命令模板中没有 --name 参数,则添加容器名称
        // 假设命令模板格式为: docker run [其他参数] image_name
        // 我们需要在 docker run 后添加 --name 参数
        String baseCommand = MessageFormat.format(docx2pdfPath, profile, fileName);
        // 检查是否包含 docker run
        if (baseCommand.contains("docker run")) {
            // 在 docker run 后插入 --name 参数
            String[] parts = baseCommand.split("docker run", 2);
            if (parts.length == 2) {
                return "docker run --name " + containerName + parts[1];
            }
        }
        // 如果无法解析,则直接返回原命令
        log.warn("无法解析Docker命令模板,使用原始命令: {}", baseCommand);
        return baseCommand;
    }
    /**
     * 获取文件锁
     */
    private FileLock acquireFileLock() {
@@ -169,33 +203,35 @@
    }
    
    /**
     * 清理旧容器
     * 清理旧容器(轻量级版本)
     */
    private void cleanupOldContainers() {
        try {
            // 查找并停止所有相关容器
            String findCommand = "docker ps -a --filter name=" + CONTAINER_NAME_PREFIX + "* --format '{{.Names}}'";
            // 只清理停止状态的容器,不干扰运行中的容器
            String findCommand = "docker ps -a --filter name=" + CONTAINER_NAME_PREFIX + "* --filter status=exited --format '{{.Names}}'";
            Process findProc = Runtime.getRuntime().exec(findCommand);
            
            BufferedReader reader = new BufferedReader(new InputStreamReader(findProc.getInputStream()));
            String containerName;
            boolean hasCleaned = false;
            
            while ((containerName = reader.readLine()) != null) {
                if (!containerName.trim().isEmpty()) {
                    log.info("清理旧容器: {}", containerName);
                    log.info("清理已停止的旧容器: {}", containerName);
                    
                    // 停止容器
                    String stopCommand = "docker stop " + containerName;
                    Runtime.getRuntime().exec(stopCommand);
                    // 删除容器
                    // 删除已停止的容器
                    String rmCommand = "docker rm " + containerName;
                    Runtime.getRuntime().exec(rmCommand);
                    hasCleaned = true;
                }
            }
            
            reader.close();
            findProc.waitFor(10, TimeUnit.SECONDS);
            findProc.waitFor(5, TimeUnit.SECONDS);
            if (!hasCleaned) {
                log.debug("没有发现需要清理的旧容器");
            }
            
        } catch (Exception e) {
            log.warn("清理旧容器时出现异常", e);
@@ -203,7 +239,7 @@
    }
    
    /**
     * 强制终止进程
     * 强制终止进程并销毁相关容器
     */
    private void forceKillProcess(Process proc) {
        try {
@@ -216,12 +252,150 @@
                    log.warn("强制终止进程");
                }
            }
            // 强制清理所有相关容器
            forceCleanupContainers();
        } catch (Exception e) {
            log.error("强制终止进程失败", e);
        }
    }
    
    /**
     * 强制清理所有相关容器
     */
    private void forceCleanupContainers() {
        try {
            log.info("开始强制清理相关容器...");
            // 清理带有特定前缀的容器
            cleanupContainersByPrefix();
            // 清理可能残留的headless-wps容器(基于镜像名称)
            cleanupContainersByImage("headless-wps-example");
            log.info("容器强制清理完成");
        } catch (Exception e) {
            log.error("强制清理容器失败", e);
        }
    }
    /**
     * 根据前缀清理容器
     */
    private void cleanupContainersByPrefix() {
        try {
            // 查找所有运行中的相关容器
            String runningCommand = "docker ps --filter name=" + CONTAINER_NAME_PREFIX + "* --format '{{.Names}}'";
            Process runningProc = Runtime.getRuntime().exec(runningCommand);
            BufferedReader runningReader = new BufferedReader(new InputStreamReader(runningProc.getInputStream()));
            String containerName;
            while ((containerName = runningReader.readLine()) != null) {
                if (!containerName.trim().isEmpty()) {
                    log.warn("强制停止运行中的容器: {}", containerName);
                    // 强制停止容器
                    String killCommand = "docker kill " + containerName;
                    Process killProc = Runtime.getRuntime().exec(killCommand);
                    killProc.waitFor(10, TimeUnit.SECONDS);
                    // 强制删除容器
                    String rmCommand = "docker rm -f " + containerName;
                    Process rmProc = Runtime.getRuntime().exec(rmCommand);
                    rmProc.waitFor(10, TimeUnit.SECONDS);
                    log.info("已强制清理容器: {}", containerName);
                }
            }
            runningReader.close();
            runningProc.waitFor(10, TimeUnit.SECONDS);
            // 查找所有停止的相关容器并删除
            String stoppedCommand = "docker ps -a --filter name=" + CONTAINER_NAME_PREFIX + "* --format '{{.Names}}'";
            Process stoppedProc = Runtime.getRuntime().exec(stoppedCommand);
            BufferedReader stoppedReader = new BufferedReader(new InputStreamReader(stoppedProc.getInputStream()));
            while ((containerName = stoppedReader.readLine()) != null) {
                if (!containerName.trim().isEmpty()) {
                    log.warn("强制删除停止的容器: {}", containerName);
                    // 强制删除容器
                    String rmCommand = "docker rm -f " + containerName;
                    Process rmProc = Runtime.getRuntime().exec(rmCommand);
                    rmProc.waitFor(10, TimeUnit.SECONDS);
                    log.info("已强制删除容器: {}", containerName);
                }
            }
            stoppedReader.close();
            stoppedProc.waitFor(10, TimeUnit.SECONDS);
        } catch (Exception e) {
            log.error("根据前缀清理容器失败", e);
        }
    }
    /**
     * 根据镜像名称清理容器
     */
    private void cleanupContainersByImage(String imageName) {
        try {
            log.info("清理镜像为 {} 的容器", imageName);
            // 查找所有运行中的相关容器
            String runningCommand = "docker ps --filter ancestor=" + imageName + " --format '{{.Names}}'";
            Process runningProc = Runtime.getRuntime().exec(runningCommand);
            BufferedReader runningReader = new BufferedReader(new InputStreamReader(runningProc.getInputStream()));
            String containerName;
            while ((containerName = runningReader.readLine()) != null) {
                if (!containerName.trim().isEmpty()) {
                    log.warn("强制停止运行中的容器: {}", containerName);
                    // 强制停止容器
                    String killCommand = "docker kill " + containerName;
                    Process killProc = Runtime.getRuntime().exec(killCommand);
                    killProc.waitFor(10, TimeUnit.SECONDS);
                    // 强制删除容器
                    String rmCommand = "docker rm -f " + containerName;
                    Process rmProc = Runtime.getRuntime().exec(rmCommand);
                    rmProc.waitFor(10, TimeUnit.SECONDS);
                    log.info("已强制清理容器: {}", containerName);
                }
            }
            runningReader.close();
            runningProc.waitFor(10, TimeUnit.SECONDS);
            // 查找所有停止的相关容器并删除
            String stoppedCommand = "docker ps -a --filter ancestor=" + imageName + " --format '{{.Names}}'";
            Process stoppedProc = Runtime.getRuntime().exec(stoppedCommand);
            BufferedReader stoppedReader = new BufferedReader(new InputStreamReader(stoppedProc.getInputStream()));
            while ((containerName = stoppedReader.readLine()) != null) {
                if (!containerName.trim().isEmpty()) {
                    log.warn("强制删除停止的容器: {}", containerName);
                    // 强制删除容器
                    String rmCommand = "docker rm -f " + containerName;
                    Process rmProc = Runtime.getRuntime().exec(rmCommand);
                    rmProc.waitFor(10, TimeUnit.SECONDS);
                    log.info("已强制删除容器: {}", containerName);
                }
            }
            stoppedReader.close();
            stoppedProc.waitFor(10, TimeUnit.SECONDS);
        } catch (Exception e) {
            log.error("根据镜像清理容器失败", e);
        }
    }
    /**
     * 清理资源
     */
    private void cleanupResources(Process proc, FileLock lock) {