jsch连接sftp后连接未释放掉问题排查

项目中通过jsch中的sftp实现上传下载文件。代码上了服务器之后,内存飙升,逐渐把swap区也占满,通过top监控未发现占用内存的进程,通过查找sshd进程,发现服务器多了很多sftp的进程没有被关闭。

刚开始以为是sftp公共方法设计的有问题,下面是部分代码片段

@Repository("SftpClient")
public class SftpClient {

    private Logger logger = LoggerFactory.getLogger(SftpClient.class);
    private ThreadLocal<Session> sessionLocal = new ThreadLocal<Session>();
    private ThreadLocal<ChannelSftp> channelLocal = new ThreadLocal<ChannelSftp>();

    //初始化连接
    public SftpClient init() {
        try {
            String host = SFTP_HOST;
            int port = Integer.valueOf(SFTP_PORT);
            String userName = SFTP_USER_NAME;
            String password = SFTP_USER_PASSWORD;
            Integer timeout = Integer.valueOf(SFTP_TIMEOUT);
            Integer aliveMax = Integer.valueOf(SFTP_ALIVEMAX);
            // 创建JSch对象
            JSch jsch = new JSch();
            Session session = jsch.getSession(userName, host, port);
            // 根据用户名,主机ip,端口获取一个Session对象
            if (password != null) {
                // 设置密码
                session.setPassword(password);
            }
            // 为Session对象设置properties
            session.setConfig("StrictHostKeyChecking", "no");
            if (timeout != null) {
                // 设置timeout时间
                session.setTimeout(timeout);
            }
            if (aliveMax != null) {
                session.setServerAliveCountMax(aliveMax);
            }
            // 通过Session建立链接
            session.connect();
            // 打开SFTP通道
            ChannelSftp channel = (ChannelSftp) session.openChannel("sftp");
            // 建立SFTP通道的连接
            channel.connect();
            channelLocal.set(channel);
            sessionLocal.set(session);
            logger.debug("SSH Channel connected.session={},channel={}", session, channel);
        } catch (JSchException e) {
            throw new SystemException(ImageExceptionCode.FTP_SEND_ERROR);
        }
        return this;
    }

    //断开连接
    public void disconnect() {
        ChannelSftp channel = channelLocal.get();
        Session session = sessionLocal.get();
        //断开sftp连接
        if (channel != null) {
            channel.disconnect();
            logger.debug("SSH Channel disconnected.channel={}", channel);
        }
        //断开sftp连接之后,再断开session连接
        if (session != null) {
            session.disconnect();
            logger.debug("SSH session disconnected.session={}", session);
        }
        channelLocal.remove();
        sessionLocal.remove();
    }
}

原文地址:https://www.cnblogs.com/zjfjava/p/11007358.html

时间: 2024-10-10 12:19:53

jsch连接sftp后连接未释放掉问题排查的相关文章

“ping”命令的原理就是向对方主机发送UDP数据包,HTTP在每次请求结束后都会主动释放连接,因此HTTP连接是一种“短连接”

Socket  是一套建立在TCP/IP协议上的接口不是一个协议 应用层:  HTTP  FTP  SMTP  Web 传输层:  在两个应用程序之间提供了逻辑而不是物理的通信(TCP  UDP) TCP  可靠的  面向连接的服务 UDP  不可靠的  无连接的服务 只要底层实现TCP IP协议  都可以用socket进行通信 1.TCP和UDP 1.1 TCP连接 TCP协议能为应用程序提供可靠的通信连接,使一台计算机发出的字节流无差错地发往网络上的其他计算机,对可靠性要求高的数据通信系统往

RHEL6删除文件后未释放空间

早上一个网站页面打开空白,后来查看是磁盘空间满了,查看是nginx的access.log占用了170多个G,于是通过rm将其删除,后重启nginx问题依然,此时再查看磁盘发现空间并未释放 [[email protected] logs]# du -h * 176G access.log 0 error.log 4.0K nginx.pid [[email protected] logs]# du -sh  176G . [[email protected] logs]# rm access.lo

【转】TCP建立连接三次握手和释放连接四次握手

在谈及TCP建立连接和释放连接过程,先来简单认识一下TCP报文段首部格式的的几个名词(这里只是简单说明,具体请查看相关教程) 序列号seq:占4个字节,用来标记数据段的顺序,TCP把连接中发送的所有数据字节都编上一个序号,第一个字节的编号由本地随机产生:给字节编上序号后,就给每一个报文段指派一个序号:序列号seq就是这个报文段中的第一个字节的数据编号.  确认号ack:占4个字节,期待收到对方下一个报文段的第一个数据字节的序号:序列号表示报文段携带数据的第一个字节的编号:而确认号指的是期望接收到

Oracle JDBC 连接卡死后 Connection Reset

坑 这绝对是我碰计算机以来遇到的第一大坑! 症状: 在Linux主机上远程登录,执行一个简单的Oracle的JDBC连接程序(jar包),结果硬生生的卡在了连接建立验证阶段,然后等上几分钟后因为连接超时,连接被远端的Oracle服务器reset,于是报了connection reset exception 原因: 参考:http://www.usn-it.de/index.php/2009/02/20/oracle-11g-jdbc-driver-hangs-blocked-by-devrand

安装mysql后连接出错(错误:Access denied for user &#39;root&#39;@&#39;localhost&#39; (using password: YES)&quot;)的解决办法

前几天下载了mysql5.7正常安装后,用navicat for mysql连接时提示"Access denied for user 'root'@'localhost' (using password: YES)""错误信息,因为第一次安装时未添加用户,所以卸载一次又重新添加了用户和密码安装后打开依然报错,借鉴了网上的一些方法,然后用自己的方法实现了连接. 解决方法: 1.打开mysql Command Line Client,输入安装mysql时设置的密码,出现如下界面:

由“Beeline连接HiveServer2后如何使用指定的队列(Yarn)运行Hive SQL语句”引发的一系列思考

背景 我们使用的HiveServer2的版本为0.13.1-cdh5.3.2,目前的任务使用Hive SQL构建,分为两种类型:手动任务(临时分析需求).调度任务(常规分析需求),两者均通过我们的Web系统进行提交.以前两种类型的任务都被提交至Yarn中一个名称为“hive”的队列,为了避免两种类型的任务之间相互受影响以及并行任务数过多导致“hive”队列资源紧张,我们在调度系统中构建了一个任务缓冲区队列,所有被提交的任务(手动任务.调度任务)并不会直接被提交至集群,而是提交至这个缓冲区队列中,

ubuntu上mysql服务器安装后只能本地连接不能远程连接的问题

安装好mysql后,想使用另一个电脑进行远程登录,在登录时 提示拒绝连接 百度后,发现需要两个步骤解决该问题 /etc/mysql/my.cnf 里修改bind_address = 0.0.0.0   进行授权 (1)直接授权 mysql>GRANT ALL PRIVILEGES ON *.* TO 'root'@'%' IDENTIFIED BY '123456' WITH GRANT OPTION; mysql>FLUSH RIVILEGES  (2)改表法 可能是你的帐号不允许从远程登陆

BAT&VBS脚本:Windows连接VPN后同时登陆内网和外网

今天连公司的VPN,发现连上去之后就登陆不了外网了,上网查了下,再加上与同事的交流,发现连接VPN后同时登陆外网需要下面几个步骤: (我的环境:Windows 7 旗舰版 Service Pack 1) 1)建立好VPN,连接VPN 2)进入到VPN属性页面 3)找到网络选项卡,选中"Internet版本协议4(TCP/IPv4)",点击下方的"属性"按钮 4)在"Internet版本协议4(TCP/IPv4)"的属性界面中,点击"高级

连接VPN后,本机不能上互联网的解决办法

连接VPN后,本机不能上互联网的解决办法 宽带拨号上了网,正常. 再创建个VPN连接到公司网络,连接正常,可以PING通公司的服务器. 再上网,上不去了! 断开VPN,上网正常,搜索引擎一搜,都说要改一个VPN网络的配置,位置: VPN连接-->属性--网络--IPV4--属性--高级 默认时,“在远程网络上使用默认网关”是勾选上的. 按网上的说法,要去掉这个勾.照办. 再连接VPN,还是不能上网. 细看上网提示,是DNS地址找不到.看来按网上所说的是路由不对的说法靠不住,问题在DNS. 于是还