使用Java连接SFTP时发生UnknownHostException

我试图上传文件连续使用java中的5个线程的SFTP服务器,在启动程序正确上传文件,但一段时间后,

所有的线程抛出UnknownHostException尝试创build新的会话和exception继续高达5至10分钟,经过一段时间程序正常工作,我无法find什么会导致这个exception,

这是用于连接sftp的代码,

JSch jsch = new JSch(); jsch.setKnownHosts(host_file); session = jsch.getSession(SFTPUSER,SFTPHOST,SFTPPORT); session.setPassword(SFTPPASS); java.util.Properties config = new java.util.Properties(); config.put("StrictHostKeyChecking", "no"); session.setConfig(config); session.connect(); channel = session.openChannel("sftp"); channel.connect(); 

例外:

  at td.bdops.clupload.CARUpload.uploadZip(CARUpload.java:398) at td.bdops.clupload.CARUpload.uploadZip(CARUpload.java:398) Caused by: java.net.UnknownHostException: sftp.opsbank2-prod.tio.systems at java.net.AbstractPlainSocketImpl.connect(Unknown Source) at java.net.PlainSocketImpl.connect(Unknown Source) at java.net.SocksSocketImpl.connect(Unknown Source) at java.net.Socket.connect(Unknown Source) at java.net.Socket.connect(Unknown Source) at java.net.Socket.<init>(Unknown Source) at java.net.Socket.<init>(Unknown Source) at com.jcraft.jsch.Util.createSocket(Util.java:343) at com.jcraft.jsch.Session.connect(Session.java:215) at com.jcraft.jsch.Session.connect(Session.java:183) at td.bdops.util.FTPUtility.uploadAWSFTP(FTPUtility.java:227) at td.bdops.util.FTPUtility.uploadAWSFTP(FTPUtility.java:247) 

任何人都可以请解释我,这个错误的根源是什么

这个问题不是一个JSCH特定的问题,你可以用stacktrace看到,因为它发生在java.net包的类中,而不是在jsch-classes中。 所以使用FileZilla进行测试在这里没有什么帮助。

我在这里可以看到的最可能的原因是名称的解析确实在某个时候失败了(内部DNS服务器不可用等)。 Java有自己的独立于操作系统的DNS缓存,所以即使你可以在命令行上得到解析的名字,Java仍然会被视为无法解析。 您可以使用系统属性networkaddress.cache.ttlnetworkaddress.cache.negative.ttl来更改该内部缓存的TTL设置。 将这两个属性中的一个或两个设置为0将导致该特定缓存的停用。

如果停用后者,您可以尝试一下,如果情况变得更好,但是您应该尝试找出问题的根源,即为什么在一天中的某个时间无法解析名称,因为禁用了缓存一个价格(即表现的损失)。

所有的线程抛出UnknownHostException当试图创建新的会话和异常继续长达5至10分钟,经过一段时间程序正常工作,我无法找到什么会导致这个异常…

这是相当自我解释。 读取UnknownHostException的javadoc :

抛出以指示主机的IP地址无法确定。

查看AbstractPlainSocketImpl的代码,我看到:

 if (addr.isUnresolved()) throw new UnknownHostException(addr.getHostName()); 

所以你的sftp.opsbank2-prod.tio.systems主机名不能解决。 这意味着Java的名称解析代码无法确定该主机名的IP是什么。

这里有一些事情要尝试:

  • 使用该主机名的IP而不是名称。
  • 使用dighost命令在该系统上查找该主机名以查看是否解析。
  • 尝试下面的代码行,看看它是否工作。 它也应该抛出:

     new java.net.Socket("unknown.host.should.throw.com", 80).close(); 
  • 立即尝试您的主机名称:

     new java.net.Socket("sftp.opsbank2-prod.tio.systems", 80).close(); 

如果您看到您的主机名不解析,那么您需要将其添加到DNS配置或/etc/hosts文件中。 如果你已经有了,那么这些文件有问题,你需要重新检查你的配置。