我正在尝试在AWS ECS容器内部引入Java应用程序,而Java无法查找主机名。
ECS设置主机名并正确设置/ etc / hosts和/etc/resolv.conf。如果我做nslookup `hostname`
我的解决方案就好了。我也可以针对/etc/resolv.conf中设置的名称服务器来解决这个问题
但是,如果我启动尝试解析主机名的java应用程序,我会收到一个异常,表明主机名无法解析。
java -version输出:
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)
所以我写了一个小测试程序:
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();
}
}
当主机名为' f17a0bdca449'时,会引发以下错误:
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
如果我使用-Djava.net.preferIPv4Stack=true
切换java以使用ipv4堆栈,我得到:
$> 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,我仍然会得到同样的东西:
$> 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]
我在我的智慧结束。有什么建议吗?
答案 0 :(得分:1)
您获取的主机信息是docker容器的主机名。 这个问题不是ecs独有的,对于在docker容器中运行的任何java应用程序都是如此。
使用ECS,您无法选择将主机名注入运行时配置。
在AWS环境中运行时,更好的解决方案是使用AWS元数据服务获取主机名。
对AWS元数据服务的http GET请求应该可以获取主机的详细信息。
http://docs.aws.amazon.com/AWSEC2/latest/UserGuide/ec2-instance-metadata.html
如果您的应用程序中包含java aws sdk,则可以使用以下类 http://docs.aws.amazon.com/AWSJavaSDK/latest/javadoc/com/amazonaws/util/EC2MetadataUtils.InstanceInfo.html