tgg53953 2023-10-13 11:34 采纳率: 0%
浏览 9

Ansible执行完毕后出现一堆ssh进程且一直存在没有自动关闭

java后端代码通过Ansible执行shell命令,使远程机器执行可执行脚本等,执行完毕后出现一堆ssh进程且一直存在没有自动关闭。
而且当我执行得越多,ssh进程就会残留得越多,最终导致我的服务器资源不够用,项目崩溃。到底该怎么解决啊?
我有了解过其实Ansible是通过ssh来进行连接操作的,所以ssh的大量出现跟我代码用Ansible执行命令有关,但实际要怎么解决呢,求帮忙!

这是我Ansible执行命令的代码:

    public AnsibleResult exec(String command) throws Exception {
        AnsibleResult ansibleResult = new AnsibleResult();
        Process process = null;
        StringBuffer normalReader = new StringBuffer();
        StringBuffer errorReader = new StringBuffer();
        try {
            String[] shellCommand = {"/bin/sh", "-c", command};

            process = Runtime.getRuntime().exec(shellCommand);
            logger.info("***************************************");
            logger.info("ansible exec shell pid:" + process.pid());
            logger.info("***************************************");
            OutStream outPut = new OutStream(process.getInputStream(), normalReader);
            OutStream error = new OutStream(process.getErrorStream(), errorReader);
            error.start();
            outPut.start();
            //5分钟超时X`
            int timeout = 5;
            int exitValue = process.waitFor(timeout, TimeUnit.MINUTES) ? 0 : 1;
            ansibleResult.setCommand(command);
            ansibleResult.setStatusCode(exitValue);
            logger.info("正确流:{}", normalReader);
            logger.info("错误流:{}", errorReader);
            ansibleResult.setNormalMsg(normalReader.toString());
            ansibleResult.setErrMsg(normalReader.toString());

        } catch (Exception e) {
            logger.error("执行命令失败!命令:{}", command, e);
            if (null != process) {
                Stream<ProcessHandle> descendants = process.descendants();
                descendants.forEach(c -> c.destroyForcibly());
                process.destroyForcibly();
            }
        } finally {
            if (null != process) {
                Stream<ProcessHandle> descendants = process.descendants();
                descendants.forEach(c -> c.destroyForcibly());
                process.destroyForcibly();
            }
        }
        return ansibleResult;
    }

ps -ef 查看进程

img


而且随着我执行上述方法,ssh进程只会越来越多。
这段代码执行了很多对远程主机文件夹移动和执行.sh脚本的操作

  • 写回答

1条回答 默认 最新

  • CSDN-Ada助手 CSDN-AI 官方账号 2023-10-13 15:23
    关注

    【以下回答由 GPT 生成】

    这个问题可能是由于Ansible在执行完毕后没有正确关闭SSH连接导致的。可以尝试修改代码来手动关闭SSH连接来解决这个问题。

    请将以下代码添加到catch块中,以确保在发生异常时关闭SSH连接:

    if (process != null) {
        process.destroy();
    }
    

    同时,建议在finally块中添加代码来确保SSH连接的关闭,即使在发生异常时也能执行到:

    finally {
        if (process != null) {
            process.destroy();
        }
    }
    

    这样做的目的是在代码执行完毕后,无论是否发生异常,都能正确关闭SSH连接,避免出现大量未关闭的SSH进程。

    相关代码修改后的示例:

    public AnsibleResult exec(String command) throws Exception {
        AnsibleResult ansibleResult = new AnsibleResult();
        Process process = null;
        StringBuffer normalReader = new StringBuffer();
        StringBuffer errorReader = new StringBuffer();
        try {
            //...原有代码...
    
            // 5分钟超时
            int timeout = 5;
            int exitValue = process.waitFor(timeout, TimeUnit.MINUTES) ? 0 : 1;
            ansibleResult.setCommand(command);
            ansibleResult.setStatusCode(exitValue);
            logger.info("正确流:{}", normalReader);
            logger.info("错误流:{}", errorReader);
            ansibleResult.setNormalMsg(normalReader.toString());
            ansibleResult.setErrMsg(normalReader.toString());
    
        } catch (Exception e) {
            logger.error("执行命令失败!命令:{}", command, e);
            if (process != null) {
                process.destroy();
            }
        } finally {
            if (process != null) {
                process.destroy();
            }
        }
    
        return ansibleResult;
    }
    

    这样修改后,每次执行命令后都会正确关闭SSH连接,避免资源泄漏和大量未关闭的SSH进程的问题。

    注意:以上解决方案只是基于代码的修改,如果问题仍然存在,可能需要进一步检查Ansible配置和环境,或者进行更多的调试和排查。


    如果你已经解决了该问题, 非常希望你能够分享一下解决方案, 写成博客, 将相关链接放在评论区, 以帮助更多的人 ^-^
    评论

报告相同问题?

问题事件

  • 创建了问题 10月13日

悬赏问题

  • ¥15 微信会员卡接入微信支付商户号收款
  • ¥15 如何获取烟草零售终端数据
  • ¥15 数学建模招标中位数问题
  • ¥15 phython路径名过长报错 不知道什么问题
  • ¥15 深度学习中模型转换该怎么实现
  • ¥15 HLs设计手写数字识别程序编译通不过
  • ¥15 Stata外部命令安装问题求帮助!
  • ¥15 从键盘随机输入A-H中的一串字符串,用七段数码管方法进行绘制。提交代码及运行截图。
  • ¥15 TYPCE母转母,插入认方向
  • ¥15 如何用python向钉钉机器人发送可以放大的图片?