首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Java无法解析主机名

问Java无法解析主机名
EN

Stack Overflow用户
提问于 2016-02-19 19:59:14
回答 1查看 2.9K关注 0票数 3

我试图在AWS容器中引入一个Java应用程序,而Java无法查找主机名。

ECS设置主机名,并正确设置/etc/host和/etc/hosts。如果我做了nslookup `hostname`,我就能很好地解决问题。我还可以根据/etc/ can中设置的名称服务器来解决这个问题。

但是,如果启动试图解析主机名的java应用程序,就会得到一个异常,表明主机名无法解析。

java -version输出:

代码语言:javascript
复制
bash# java -version
java version "1.8.0_45"
Java(TM) SE Runtime Environment (build 1.8.0_45-b14)
Java HotSpot(TM) 64-Bit Server VM (build 25.45-b02, mixed mode)

所以我写了一个小测试程序:

代码语言:javascript
复制
import java.net.InetAddress;
import java.net.UnknownHostException;
import java.io.PrintWriter;
import java.io.StringWriter;

public class DomainResolutionTest {

    public static void main(String[] args) {

        try {
            InetAddress ip = InetAddress.getLocalHost();
            System.out.println(ip.toString());
        }catch (UnknownHostException uhx) {
            System.out.println("ERROR: " + uhx.getMessage() + "\n" + getStackTrace(uhx));
            Throwable cause = uhx.getCause();
            if (cause != null) System.out.println("CAUSE: " + cause.getMessage());
        }

    }

    public static String getStackTrace(Throwable t)
    {
        StringWriter sw = new StringWriter();
        PrintWriter pw = new PrintWriter(sw, true);
        t.printStackTrace(pw);
        pw.flush();
        sw.flush();
        return sw.toString();
    }

}

当主机名为‘f17a0bdca 449’时,引发以下错误:

代码语言:javascript
复制
ERROR: f17a0bdca449: f17a0bdca449: unknown error
java.net.UnknownHostException: f17a0bdca449: f17a0bdca449: unknown error
    at java.net.InetAddress.getLocalHost(InetAddress.java:1484)
    at DomainResolutionTest.main(DomainResolutionTest.java:11)
Caused by: java.net.UnknownHostException: f17a0bdca449: unknown error
    at java.net.Inet6AddressImpl.lookupAllHostAddr(Native Method)
    at java.net.InetAddress$2.lookupAllHostAddr(InetAddress.java:907)
    at java.net.InetAddress.getAddressesFromNameService(InetAddress.java:1302)
    at java.net.InetAddress.getLocalHost(InetAddress.java:1479)
    ... 1 more

CAUSE: f17a0bdca449: unknown error

如果我将java转换为使用ipv4堆栈使用-Djava.net.preferIPv4Stack=true,则会得到:

代码语言:javascript
复制
$> java -Djava.net.preferIPv4Stack=true DomainResolutionTest
ERROR: f17a0bdca449: f17a0bdca449: unknown error
java.net.UnknownHostException: f17a0bdca449: f17a0bdca449: unknown error
    at java.net.InetAddress.getLocalHost(InetAddress.java:1484)
    at DomainResolutionTest.main(DomainResolutionTest.java:11)
Caused by: java.net.UnknownHostException: f17a0bdca449: unknown error
    at java.net.Inet4AddressImpl.lookupAllHostAddr(Native Method)
    at java.net.InetAddress$2.lookupAllHostAddr(InetAddress.java:907)
    at java.net.InetAddress.getAddressesFromNameService(InetAddress.java:1302)
    at java.net.InetAddress.getLocalHost(InetAddress.java:1479)
    ... 1 more

CAUSE: f17a0bdca449: unknown error

如果我强迫它使用sun实现并指定NAMESERVER和SEARCH_DOMAIN,则仍然得到相同的内容:

代码语言:javascript
复制
$> export NAMESERVER=$(cat /etc/resolv.conf | grep nameserver | awk '{print $2}')
$> export SEARCH_DOMAIN=$(cat /etc/resolv.conf | grep search | awk '{print $2}')
$> java -Dsun.net.spi.nameservice.provider.1=dns,sun -Dsun.net.spi.nameservice.nameservers=${NAMESERVER} -Dsun.net.spi.nameservice.domain=${SEARCH_DOMAIN} -Djava.net.preferIPv4Stack=true DomainResolutionTest
ERROR: f17a0bdca449: DNS name not found [response code 3]
java.net.UnknownHostException: f17a0bdca449: DNS name not found [response code 3]
    at java.net.InetAddress.getLocalHost(InetAddress.java:1484)
    at DomainResolutionTest.main(DomainResolutionTest.java:11)
Caused by: java.net.UnknownHostException: DNS name not found [response code 3]
    at sun.net.spi.nameservice.dns.DNSNameService.resolve(DNSNameService.java:180)
    at sun.net.spi.nameservice.dns.DNSNameService.lookupAllHostAddr(DNSNameService.java:351)
    at java.net.InetAddress.getAddressesFromNameService(InetAddress.java:1302)
    at java.net.InetAddress.getLocalHost(InetAddress.java:1479)
    ... 1 more

CAUSE: DNS name not found [response code 3]

我快疯了。有什么建议吗?

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2016-05-16 00:21:37

您所获得的主机信息是码头容器的主机名。这个问题并不是ecs独有的,对于在docker容器中运行的任何java应用程序来说都是如此。

对于ECS,您没有将主机名作为运行时配置的选项。

在AWS环境中运行时,更好的解决方案是使用AWS元数据服务获取主机名。

对AWS元数据服务的http请求应该会为您提供主机的详细信息。

http://docs.aws.amazon.com/AWSEC2/latest/UserGuide/ec2-instance-metadata.html

如果应用程序中包含了java,则可以利用以下类http://docs.aws.amazon.com/AWSJavaSDK/latest/javadoc/com/amazonaws/util/EC2MetadataUtils.InstanceInfo.html

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/35513909

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档