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

Posted zjfjava

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了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();
    

 

以上是关于jsch连接sftp后连接未释放掉问题排查的主要内容,如果未能解决你的问题,请参考以下文章

连接获取上传sftp远程目录信息的工具类FtpsFileList

并发下sftp连接报错——com.jcraft.jsch.JSchException: connection is closed by foreign host

记一次排查mysql数据库连接未关闭问题的过程

jsch的sftp在多线程下的问题及处理办法

jsch上传(基于sftp协议)

如何使用jcraft 模拟SFTP登陆