首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何让Java遵守DNS缓存超时?

如何让Java遵守DNS缓存超时?
EN

Stack Overflow用户
提问于 2009-08-10 18:49:48
回答 6查看 117.2K关注 0票数 111

我们使用GSLB进行地理分布和负载均衡。每个服务都会分配一个固定的域名。通过一些DNS魔术,域名被解析成一个最接近负载最少的服务器的IP。要使负载平衡工作,应用程序服务器需要接受来自DNS响应的TTL,并在缓存超时时再次解析域名。然而,我想不出一种用Java实现这一点的方法。

该应用程序使用Java5,在Linux (Centos 5)上运行。

EN

回答 6

Stack Overflow用户

发布于 2013-06-21 00:50:25

根据拜伦的回答,您不能通过使用-D标志或调用System.setProperty来将networkaddress.cache.ttlnetworkaddress.cache.negative.ttl设置为系统属性,因为这些不是系统属性-它们是安全属性。

如果要使用系统属性触发此行为(以便可以使用-D标志或调用System.setProperty),则需要设置以下系统属性:

代码语言:javascript
复制
-Dsun.net.inetaddr.ttl=0

此系统属性将启用所需的效果。

但是请注意:如果您在启动JVM进程时没有使用-D标志,而是选择从代码调用它:

代码语言:javascript
复制
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并在该文件中设置这些安全属性,例如

代码语言:javascript
复制
networkaddress.cache.ttl = 0
networkaddress.cache.negative.ttl = 0

但请注意这些属性周围的注释中的安全警告。只有当您有理由相信自己不会感染DNS spoofing attacks时,才能这样做。

票数 86
EN

Stack Overflow用户

发布于 2013-03-08 05:24:28

这显然已经在较新的版本(SE 6和7)中得到了修复。在使用tcpdump查看端口53活动的同时运行以下代码片段时,我遇到了最大30秒的缓存时间。

代码语言:javascript
复制
/**
 * 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();
        }
    }
}
票数 22
EN

Stack Overflow用户

发布于 2009-08-10 19:33:05

为了深入了解拜伦的回答,我认为您需要编辑%JRE_HOME%\lib\security目录中的java.security文件才能使此更改生效。

以下是相关部分:

代码语言:javascript
复制
#
# 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的文档。

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

https://stackoverflow.com/questions/1256556

复制
相关文章

相似问题

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