问题描述
看到前人的代码中使用 Sftp sftp = new Sftp(sshHost, sshPort, sshUser, sshPass) ; 来创建一个Sftp客户端,然后照样也用了它,在测试时发现跑着跑着突然出现了问题,就连简单的创建目录(sftp.mkDirs(path))都不行了,经过一翻折腾,发现有多个调度使用了 Sftp sftp = new Sftp(sshHost, sshPort, sshUser, sshPass) ; 问题就出在这里,在创建Sftp客户端时 Session 默认是单例的,在并发创建Sftp时,只要其中一个线程执行完后调用sftp.close();关闭资源时,Session 也就关闭了,由于是单例的,其他线程创建的Sftp也就挂了;所以当有多个线程使用Sftp时,Session最好是多例的,这样单个关闭也不会影响到其他的;
解决方案
Sftp sftp = new Sftp(sshHost, sshPort, sshUser, sshPass);
换成 ↓
Sftp sftp = new Sftp(JschUtil.openSession(sshHost, sshPort, sshUser, sshPass));
Sftp(sshHost, sshPort, sshUser, sshPass) 分析
会重用已经存在的Session
Sftp(Session session) 分析
你自己传一个Session过去,随便你是新的还是老的,JschUtil工具类还有其他一些创建Session的方法
吐槽
hutool的Sftp类应该再提供一个构造方法出来,多加一个Session的模式参数,让使用者根据自己的需求来传,这样就不会等出问题了再去看源码才发现问题所在
另外还有一坑 delFile(String filePath)
在删除一个有多个层级文件时,只要其中有一个目录不存在,就会抛异常了
|