使用Java连接SFTP时发生UnknownHostException

使用Java连接SFTP时发生UnknownHostException,java,linux,amazon-ec2,sftp,jsch,Java,Linux,Amazon Ec2,Sftp,Jsch,我正在尝试使用java中的5个线程将文件连续上传到SFTP服务器, 在启动时,程序会正确上载文件,但一段时间后 所有线程在尝试创建新会话时抛出UnknownHostException,异常持续5到10分钟,程序正常运行一段时间后,我无法找到导致此异常的原因 这是用于连接sftp的代码 JSch jsch = new JSch(); jsch.setKnownHosts(host_file); session = jsch.getSession(SF

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

所有线程在尝试创建新会话时抛出UnknownHostException,异常持续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)
位于td.bdops.clupload.CARUpload.uploadZip(CARUpload.java:398)
位于td.bdops.clupload.CARUpload.uploadZip(CARUpload.java:398)
原因:java.net.UnknownHostException:sftp.opsbank2-prod.tio.systems
位于java.net.AbstractPlainSocketImpl.connect(未知源)
位于java.net.PlainSocketImpl.connect(未知源)
位于java.net.socksocketimpl.connect(未知源)
位于java.net.Socket.connect(未知源)
位于java.net.Socket.connect(未知源)
位于java.net.Socket。(未知源)
位于java.net.Socket。(未知源)
位于com.jcraft.jsch.Util.createSocket(Util.java:343)
位于com.jcraft.jsch.Session.connect(Session.java:215)
位于com.jcraft.jsch.Session.connect(Session.java:183)
在td.bdops.util.FTPUtility.uploadAWSFTP(FTPUtility.java:227)
在td.bdops.util.FTPUtility.uploadAWSFTP(FTPUtility.java:247)

有人能解释一下,这个错误的根本原因是什么吗?这个问题不是JSCH特有的问题,因为它发生在java.net包的一个类中,而不是JSCH类中。因此,使用FileZilla进行测试在这里没有多大帮助

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

如果停用后者,情况会有所好转,您可以进行尝试,但您应该尝试找出问题的根源,即为什么您在一天中的某个时间无法解析名称,因为停用缓存是有代价的(即性能损失)

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

这是不言自明的。阅读:

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

查看
AbstractPlainSocketImpl
的代码,我看到:

if (addr.isUnresolved())
   throw new UnknownHostException(addr.getHostName());
因此,您的
sftp.opsbank2-prod.tio.systems
主机名无法解析。这意味着Java的名称解析代码无法确定该主机名的IP是什么

以下是一些可以尝试的东西:

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

    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
文件中。如果您已经安装了,那么这些文件有问题,您需要重新检查配置。

目标主机有没有可能出现故障?我想一些打开的套接字没有正确关闭。我建议你先复习/修改课程。如果错误仍然发生,也许您可以尝试@Xvolks no中的解决方案,但在发生此异常时,我仍然可以通过FileZilla访问主机。如果有帮助,请确保接受答案。