我们使用GSLB进行地理分布和负载均衡。每个服务都会分配一个固定的域名。通过一些DNS魔术,域名被解析成一个最接近负载最少的服务器的IP。要使负载平衡工作,应用程序服务器需要接受来自DNS响应的TTL,并在缓存超时时再次解析域名。然而,我想不出一种用Java实现这一点的方法。
该应用程序使用Java5,在Linux (Centos 5)上运行。
发布于 2013-06-21 00:50:25
根据拜伦的回答,您不能通过使用-D标志或调用System.setProperty来将networkaddress.cache.ttl或networkaddress.cache.negative.ttl设置为系统属性,因为这些不是系统属性-它们是安全属性。
如果要使用系统属性触发此行为(以便可以使用-D标志或调用System.setProperty),则需要设置以下系统属性:
-Dsun.net.inetaddr.ttl=0此系统属性将启用所需的效果。
但是请注意:如果您在启动JVM进程时没有使用-D标志,而是选择从代码调用它:
java.security.Security.setProperty("networkaddress.cache.ttl" , "0")此代码必须在JVM中的任何其他代码尝试执行网络操作之前执行。
这一点很重要,因为,例如,如果您在.war文件中调用Security.setProperty并将该.war部署到Tomcat,这将不起作用: Tomcat使用Java网络堆栈进行自身初始化,这比执行.war的代码要早得多。由于这种“竞争条件”,在启动JVM进程时使用-D标志通常更方便。
如果不使用-Dsun.net.inetaddr.ttl=0或调用Security.setProperty,则需要编辑$JRE_HOME/lib/security/java.security并在该文件中设置这些安全属性,例如
networkaddress.cache.ttl = 0
networkaddress.cache.negative.ttl = 0但请注意这些属性周围的注释中的安全警告。只有当您有理由相信自己不会感染DNS spoofing attacks时,才能这样做。
发布于 2013-03-08 05:24:28
这显然已经在较新的版本(SE 6和7)中得到了修复。在使用tcpdump查看端口53活动的同时运行以下代码片段时,我遇到了最大30秒的缓存时间。
/**
* http://stackoverflow.com/questions/1256556/any-way-to-make-java-honor-the-dns-caching-timeout-ttl
*
* Result: Java 6 distributed with Ubuntu 12.04 and Java 7 u15 downloaded from Oracle have
* an expiry time for dns lookups of approx. 30 seconds.
*/
import java.util.*;
import java.text.*;
import java.security.*;
import java.net.InetAddress;
import java.net.UnknownHostException;
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.io.InputStream;
import java.net.URL;
import java.net.URLConnection;
public class Test {
final static String hostname = "www.google.com";
public static void main(String[] args) {
// only required for Java SE 5 and lower:
//Security.setProperty("networkaddress.cache.ttl", "30");
System.out.println(Security.getProperty("networkaddress.cache.ttl"));
System.out.println(System.getProperty("networkaddress.cache.ttl"));
System.out.println(Security.getProperty("networkaddress.cache.negative.ttl"));
System.out.println(System.getProperty("networkaddress.cache.negative.ttl"));
while(true) {
int i = 0;
try {
makeRequest();
InetAddress inetAddress = InetAddress.getLocalHost();
System.out.println(new Date());
inetAddress = InetAddress.getByName(hostname);
displayStuff(hostname, inetAddress);
} catch (UnknownHostException e) {
e.printStackTrace();
}
try {
Thread.sleep(5L*1000L);
} catch(Exception ex) {}
i++;
}
}
public static void displayStuff(String whichHost, InetAddress inetAddress) {
System.out.println("Which Host:" + whichHost);
System.out.println("Canonical Host Name:" + inetAddress.getCanonicalHostName());
System.out.println("Host Name:" + inetAddress.getHostName());
System.out.println("Host Address:" + inetAddress.getHostAddress());
}
public static void makeRequest() {
try {
URL url = new URL("http://"+hostname+"/");
URLConnection conn = url.openConnection();
conn.connect();
InputStream is = conn.getInputStream();
InputStreamReader ird = new InputStreamReader(is);
BufferedReader rd = new BufferedReader(ird);
String res;
while((res = rd.readLine()) != null) {
System.out.println(res);
break;
}
rd.close();
} catch(Exception ex) {
ex.printStackTrace();
}
}
}发布于 2009-08-10 19:33:05
为了深入了解拜伦的回答,我认为您需要编辑%JRE_HOME%\lib\security目录中的java.security文件才能使此更改生效。
以下是相关部分:
#
# The Java-level namelookup cache policy for successful lookups:
#
# any negative value: caching forever
# any positive value: the number of seconds to cache an address for
# zero: do not cache
#
# default value is forever (FOREVER). For security reasons, this
# caching is made forever when a security manager is set. When a security
# manager is not set, the default behavior is to cache for 30 seconds.
#
# NOTE: setting this to anything other than the default value can have
# serious security implications. Do not set it unless
# you are sure you are not exposed to DNS spoofing attack.
#
#networkaddress.cache.ttl=-1 有关java.security文件here的文档。
https://stackoverflow.com/questions/1256556
复制相似问题