使用Java连接SFTP时发生UnknownHostException

时间:2017-09-02 12:13:54

标签: java linux amazon-ec2 sftp jsch

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

在尝试创建新会话时,所有线程都会抛出UnknownHostException,并且Exception会持续5到10分钟,在一段时间程序正常工作后,我无法找到导致此异常的原因,

这是用于连接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)

任何人都可以解释一下,这个错误的根本原因是什么

2 个答案:

答案 0 :(得分:1)

问题不是特定于JSCH的问题,因为它可以在堆栈跟踪中看到,因为它发生在java.net包的一个类中,而不是在jsch-classes中。因此,使用FileZilla进行测试对此没什么帮助。

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

如果您停用后者,情况会好转,但您应该尝试找出问题的根源,例如为什么您无法在白天的某个时间解析名称,因为停用了缓存带有价格(即性能损失)。

答案 1 :(得分:0)

  

所有线程在尝试创建新会话时抛出UnknownHostException并且异常持续5到10分钟,在一段时间程序正常工作后,我无法找到导致此异常的原因...

这是非常自我解释的。阅读javadocs for UnknownHostException

  

抛出表示无法确定主机的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文件中。如果您已经有,那么这些文件有问题,您需要重新检查配置。