Java 程序和 tomcat 中的代码 运行 返回的 IP 地址不正确
Incorrect IP address returned to Java program and code running in tomcat
OS: Red Hat Enterprise Linux Server release 6.6 (Santiago)
Java jdk1.8.0_45
独立程序和 tomcat 中的代码 运行 为少数主机名返回了错误的 IP 地址。
同一台机器上的 dig 和 nslookup 返回正确的 IP。
使用 strace -s 2048 -o strace_log -ff
没有产生任何有用的故障排除信息。
使用 -Dsun.net.spi.nameservice.nameservers=8.8.8.8
或本地 DNS 服务器(由 nslookup 和 dig 使用)returns 相同的错误地址。
[INFO] sun.net.InetAddressCachePolicy.get() = 30
[INFO] sun.net.spi.nameservice.provider.1 = null
[INFO] sun.net.spi.nameservice.nameservers = 8.8.8.8
使用 dnsjava 和 -Dsun.net.spi.nameservice.provider.1="dns,dnsjava"
returns 正确的 IP 地址。
如何检查 java 实际使用的名称服务器?
或者有更多的故障排除技巧吗?
谢谢
Test.sh
#!/bin/sh
HOST=REMOVED
NAMESERVER=LOCAL_NAME_SERVER_IP
NAMESERVER=8.8.8.8
# -Djava.net.preferIPv4Stack=true \ #-Dsun.net.spi.nameservice.nameservers=$NAMESERVER \
# -javaagent:dnslog.jar \
# -Dsun.net.spi.nameservice.provider.1="dns,dnsjava" \
# -cp ".:./dnsjava-2.1.8.jar" \
javac Test.java
rm strace_log.*
strace -s 2048 -o strace_log -ff java \
-Djava.net.preferIPv4Stack=true \
-Dsun.net.spi.nameservice.nameservers=$NAMESERVER \
Test https://$HOST
dig $HOST > ${HOST}_dig.txt
nslookup $HOST > ${HOST}_nslookup.txt
java -cp "./dnsjava-2.1.8.jar" dig $HOST > ${HOST}_dnsjava.txt
Test.java
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.net.*;
import java.util.logging.*;
public class Test extends Formatter {
public static void main(String[] args) throws Exception {
Logger log = Logger.getLogger(Test.class.getName());
log.setUseParentHandlers(false);
ConsoleHandler handler = new ConsoleHandler();
handler.setFormatter(new Test());
log.addHandler(handler);
log.info("sun.net.InetAddressCachePolicy.get() = " + sun.net.InetAddressCachePolicy.get());
log.info("sun.net.spi.nameservice.provider.1 = " + System.getProperty("sun.net.spi.nameservice.provider.1"));
log.info("sun.net.spi.nameservice.nameservers = " + System.getProperty("sun.net.spi.nameservice.nameservers"));
try {
if (args.length != 1 && args.length != 2) {
log.warning("Usage: java Test <https://address.server.edu> [timeout]");
return;
}
log.info("Received host address " + args[0]);
URL constructedUrl = new URL(args[0]);
String host = constructedUrl.getHost();
InetAddress address = InetAddress.getByName(host);
String ip = address.getHostAddress();
log.info("Host = " + args[0] + " IP = " + ip);
InetAddress Address = InetAddress.getLocalHost();
log.info("InetAddress.getLocalHost() = " + Address);
log.info("InetAddress.getCanonicalHostName() = " + Address.getCanonicalHostName());
InetAddress SW[] = InetAddress.getAllByName(host);
for (int i=0; i < SW.length; i++) {
log.info("getAllByName[" + i + "] = " + SW[i]);
}
URLConnection conn = constructedUrl.openConnection();
if (args.length == 2) {
conn.setConnectTimeout(Integer.valueOf(args[1]) * 1000);
} else {
conn.setConnectTimeout(5000);
}
log.info("Setting connection timeout to " + conn.getConnectTimeout() / 1000 + " second(s).");
log.info("Trying to connect to " + args[0]);
InputStreamReader reader = new InputStreamReader(conn.getInputStream(), "UTF-8");
BufferedReader in = new BufferedReader(reader);
in.readLine();
in.close();
reader.close();
log.info("Great! It worked.");
} catch (Exception e) {
log.info("Could not connect to the host address " + args[0]);
log.info("The error is: " + e.getMessage());
log.info("Here are the details:");
log.log(Level.SEVERE, e.getMessage(), e);
throw new RuntimeException(e);
}
}
public String format(LogRecord record) {
StringBuffer sb = new StringBuffer();
sb.append("[");
sb.append(record.getLevel().getName());
sb.append("]\t");
sb.append(formatMessage(record));
sb.append("\n");
return sb.toString();
}
}
问题已通过重新启动 nscd 守护进程解决。它有点挂起,因为有许多 nscd -i hosts
已处理 运行,但它仍在响应来自应用程序的查询。这可能解释了为什么 DNS TTL 不受尊重。
OS: Red Hat Enterprise Linux Server release 6.6 (Santiago)
Java jdk1.8.0_45
独立程序和 tomcat 中的代码 运行 为少数主机名返回了错误的 IP 地址。
同一台机器上的 dig 和 nslookup 返回正确的 IP。
使用 strace -s 2048 -o strace_log -ff
没有产生任何有用的故障排除信息。
使用 -Dsun.net.spi.nameservice.nameservers=8.8.8.8
或本地 DNS 服务器(由 nslookup 和 dig 使用)returns 相同的错误地址。
[INFO] sun.net.InetAddressCachePolicy.get() = 30
[INFO] sun.net.spi.nameservice.provider.1 = null
[INFO] sun.net.spi.nameservice.nameservers = 8.8.8.8
使用 dnsjava 和 -Dsun.net.spi.nameservice.provider.1="dns,dnsjava"
returns 正确的 IP 地址。
如何检查 java 实际使用的名称服务器? 或者有更多的故障排除技巧吗?
谢谢
Test.sh
#!/bin/sh
HOST=REMOVED
NAMESERVER=LOCAL_NAME_SERVER_IP
NAMESERVER=8.8.8.8
# -Djava.net.preferIPv4Stack=true \ #-Dsun.net.spi.nameservice.nameservers=$NAMESERVER \
# -javaagent:dnslog.jar \
# -Dsun.net.spi.nameservice.provider.1="dns,dnsjava" \
# -cp ".:./dnsjava-2.1.8.jar" \
javac Test.java
rm strace_log.*
strace -s 2048 -o strace_log -ff java \
-Djava.net.preferIPv4Stack=true \
-Dsun.net.spi.nameservice.nameservers=$NAMESERVER \
Test https://$HOST
dig $HOST > ${HOST}_dig.txt
nslookup $HOST > ${HOST}_nslookup.txt
java -cp "./dnsjava-2.1.8.jar" dig $HOST > ${HOST}_dnsjava.txt
Test.java
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.net.*;
import java.util.logging.*;
public class Test extends Formatter {
public static void main(String[] args) throws Exception {
Logger log = Logger.getLogger(Test.class.getName());
log.setUseParentHandlers(false);
ConsoleHandler handler = new ConsoleHandler();
handler.setFormatter(new Test());
log.addHandler(handler);
log.info("sun.net.InetAddressCachePolicy.get() = " + sun.net.InetAddressCachePolicy.get());
log.info("sun.net.spi.nameservice.provider.1 = " + System.getProperty("sun.net.spi.nameservice.provider.1"));
log.info("sun.net.spi.nameservice.nameservers = " + System.getProperty("sun.net.spi.nameservice.nameservers"));
try {
if (args.length != 1 && args.length != 2) {
log.warning("Usage: java Test <https://address.server.edu> [timeout]");
return;
}
log.info("Received host address " + args[0]);
URL constructedUrl = new URL(args[0]);
String host = constructedUrl.getHost();
InetAddress address = InetAddress.getByName(host);
String ip = address.getHostAddress();
log.info("Host = " + args[0] + " IP = " + ip);
InetAddress Address = InetAddress.getLocalHost();
log.info("InetAddress.getLocalHost() = " + Address);
log.info("InetAddress.getCanonicalHostName() = " + Address.getCanonicalHostName());
InetAddress SW[] = InetAddress.getAllByName(host);
for (int i=0; i < SW.length; i++) {
log.info("getAllByName[" + i + "] = " + SW[i]);
}
URLConnection conn = constructedUrl.openConnection();
if (args.length == 2) {
conn.setConnectTimeout(Integer.valueOf(args[1]) * 1000);
} else {
conn.setConnectTimeout(5000);
}
log.info("Setting connection timeout to " + conn.getConnectTimeout() / 1000 + " second(s).");
log.info("Trying to connect to " + args[0]);
InputStreamReader reader = new InputStreamReader(conn.getInputStream(), "UTF-8");
BufferedReader in = new BufferedReader(reader);
in.readLine();
in.close();
reader.close();
log.info("Great! It worked.");
} catch (Exception e) {
log.info("Could not connect to the host address " + args[0]);
log.info("The error is: " + e.getMessage());
log.info("Here are the details:");
log.log(Level.SEVERE, e.getMessage(), e);
throw new RuntimeException(e);
}
}
public String format(LogRecord record) {
StringBuffer sb = new StringBuffer();
sb.append("[");
sb.append(record.getLevel().getName());
sb.append("]\t");
sb.append(formatMessage(record));
sb.append("\n");
return sb.toString();
}
}
问题已通过重新启动 nscd 守护进程解决。它有点挂起,因为有许多 nscd -i hosts
已处理 运行,但它仍在响应来自应用程序的查询。这可能解释了为什么 DNS TTL 不受尊重。