微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

长时间运行的Jsch执行通道的连接丢失了一半

如何解决长时间运行的Jsch执行通道的连接丢失了一半

我们有一个运行在AWS EC2实例上的Java春季启动应用程序,该应用程序使用Jsch远程连接到本地Unix系统,并打开exec通道来压缩大文件,这是必需的一部分。我们正在观察的问题是它正在发送命令,并且正在远程服务器中执行该命令,并且应用程序正在等待命令完成,但没有获得结果继续执行(最终等待),这是代码


        try{    
        channel=(ChannelExec)session.openChannel("exec");
        channel.setCommand("xz -9 /tmp/test.dat");
        OutputStream out = System.out;
        channel.setoutputStream(out);
        channel.setErrStream(out)
        InputStream commandOutput = channel.getExtInputStream();
        
        StringBuilder outputBuffer = new StringBuilder();
        StringBuilder errorBuffer = new StringBuilder();
        
        InputStream in = channel.getInputStream();
        InputStream err = channel.getExtInputStream();
        
        channel.connect();
        
        byte[] tmp = new byte[1024];
        while (true) {
            while (in.available() > 0) {
                int i = in.read(tmp,1024);
                if (i < 0) break;
                outputBuffer.append(new String(tmp,i));
            }
            while (err.available() > 0) {
                int i = err.read(tmp,1024);
                if (i < 0) break;
                errorBuffer.append(new String(tmp,i));
            }
            if (channel.isClosed()) {
                if ((in.available() > 0) || (err.available() > 0)) continue; 
                System.out.println("exit-status: " + channel.getExitStatus());
                break;
            }
            try { 
              Thread.sleep(1000);
            } catch (Exception ee) {
            }
        }
        
        System.out.println("output: " + outputBuffer.toString());
        System.out.println("error: " + errorBuffer.toString());
      }finally{    
        channel.disconnect();
      }

因此,远程服务器上的文件压缩将需要2-3个小时才能完成。即使完成没有在API端打印输出,也没有ERROR或异常,并且它一直在等待服务器的响应。我最初以为API挂了。但是它正在处理其他请求。

在谷歌搜索中,我发现了一个博客https://blog.stephencleary.com/2009/05/detection-of-half-open-dropped.html,其中的解释似乎与我的情况相符-半掉线的连接,其中一方(这里是远程服务器)在闲置一段时间后似乎正在关闭连接时间长了-但是没有通知API方面,因此它一直在等待,希望它会返回一些东西。

只是要确保会话/连接的空闲时间是问题所在(此处,API发送压缩命令,这是一个长期运行的命令,仅在完成后才将输出返回到底层套接字) 因此,我每10分钟在同一个exec对象上引入另一个session通道,该通道只会向远程服务器发送一个ls -lrt命令,以确保连接不会空闲。可行!现在,即使压缩命令花费了很长时间-它也可以恢复响应。

我的问题是,有没有其他方法可以解决此问题,可能是我不太想避免轮询命令主动激活会话。

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。