Java Dns Cache Manipulator

Apache
Java 查看源码»
跨平台
阿里巴巴
2015-04-06
oldratlee

Java Dns Cache Manipulator(DCM) Library

通过代码直接设置Java的DNS(实际上设置的是DNS Cache),支持JDK 6+,支持IPv6。

功能

  • 设置/重置DNS(不会再去Lookup DNS)

    • 可以设置单条

    • 或是通过Properties文件批量设置

  • 清空DNS Cache(即所有的域名重新Lookup DNS)

  • 删除一条DNS Cache(即重新Lookup DNS)

  • 查看DNS Cache内容

  • 修改/查看JVM缺省的DNS的缓存时间

需求场景

  1. 一些库中写死了连接域名,需要通过修改host文件绑定才能做测试。结果是:

    • 自动持续集成的机器上一般同学是没有权限去修改host文件的,导致项目不能持续集成。
      实际上是因为这点,催生这个库的需求。

    • 单元测试需要每个开发都在开发机上做host绑定,增加了依赖的配置操作且繁琐重复。

  2. 一些功能需要域名作为输入参数,如使用HTTP请求的网关 或是 有域名检查限制的Web应用。
    这种情况下,让需要让一个域名连接到测试机器的IP上,或是 使用一个还不存在的域名但又不想或不能去配置DNS。

  3. 在性能测试时,

    • 不去做网络的DNS Lookup(DNS解析消耗),这样使得压测更加关注服务器响应,压测更充分反应出实现代码的性能。

    • 可以动态修改DNS缓存,无需修改host文件和http链接等不灵活的方式。

    • 一个JVM进程可以对应一套域名绑定,相互之间不影响,可以实现多场景,多域名绑定的需求压测。

  4. 打开Java中的SecurityManager时(如在Web容器Tomcat中的Web应用),Java的DNS缺省是不会失效的。 如果域名绑定的IP变了,可以通过这个库重置DNS,作为一个临时的手段(强烈不推荐)。

    • 通过Java Dns Cache Manipulator Tool修改运行中JVM DNS Cache。
      无需应用包含了Java Dns Cache Manipulator Library依赖(即Jar)。

    • 或通过执行入口调用Java Dns Cache Manipulator Library的方法,比如远程调用或是jvm-ssh-groovy-shell
      需要应用已经包含了Java Dns Cache Manipulator Library依赖(即Jar)。

User Guide

通过类DnsCacheManipulator设置DNS。

直接设置

DnsCacheManipulator.setDnsCache("www.hello.com", "192.168.1.1");
DnsCacheManipulator.setDnsCache("www.world.com", "1234:5678:0:0:0:0:0:200e"); 
// 支持IPv6地址 
// 之后Java代码中使用到域名都会解析成上面指定的IP。 
// 下面是一个简单获取域名对应的IP,演示一下: 
String ip = InetAddress.getByName("www.hello.com").getHostAddress(); // ip = "192.168.1.1"
 String ipv6 = InetAddress.getByName("www.world.com").getHostAddress(); // ipv6 = "1234:5678:0:0:0:0:0:200e"

通过dns-cache.properties文件批量配置

在代码测试中,会期望把域名绑定写在配置文件。

使用方式如下:

在ClassPath上,提供文件dns-cache.properties:

# 配置格式: # <host> = <ip> www.hello-world.com=192.168.1.1
www.foo.com=192.168.1.2

然后通过下面的一行代码完成批量设置:

DnsCacheManipulator.loadDnsCacheConfig();

在单元测试中,往往会写在测试类的setUp方法中,如:

@BeforeClass public static void beforeClass() throws Exception {
    DnsCacheManipulator.loadDnsCacheConfig();
}

清空JVM DNS Cache

DnsCacheManipulator.clearDnsCache();

删除一条DNS Cache

即重新Lookup DNS。

DnsCacheManipulator.removeDnsCache("baidu.com");

查看JVM DNS Cache

DnsCache dnsCache = DnsCacheManipulator.getWholeDnsCache() 
System.out.println(dnsCache);

修改/查看JVM缺省的DNS的缓存时间

// 查看缓存时间,单位秒。-1表示永远缓存,0表示不缓存 
int cachePolicy = DnsCacheManipulator.getDnsCachePolicy(); // 设置缓存时间
DnsCacheManipulator.setDnsCachePolicy(2); // 查看未命中条目的缓存时间
DnsCacheManipulator.getDnsNegativeCachePolicy() // 设置未命中条目的缓存时间
DnsCacheManipulator.setDnsNegativeCachePolicy(0);

使用注意

  • 域名不区分大小写,域名会统一转成小写,再进入DNS Cache。
    其中一个引发的现象是,DNS查询结果的域名会和输入的域名大小写不同,如果输入的域名有大写字母。

  • 对于已经完成解析保存了IP的逻辑,修改JVM DNS缓存,不会生效!可以重新创建 连接或Client解决。
    如对于HttpClient:

HttpClient client = new HttpClient();
GetMethod m1 = new GetMethod("http://www.baidu.com");
client.executeMethod(m1); 
String content = m1.getResponseBodyAsString(); // 修改DNS,绑定到自己的机器
DnsCacheManipulator.setDnsCache("www.baidu.com", "192.168.1.1"); // 重新执行m1,仍然是老结果
client.executeMethod(m1);
String content = m1.getResponseBodyAsString(); // 重新创建GetMethod,才能得到自己机器上的结果
GetMethod m2 = new GetMethod("http://www.baidu.com");
client.executeMethod(m2);
content = m2.getResponseBodyAsString();

更多详细功能

参见类DnsCacheManipulator的文档说明。

经过测试的JDK

                JDK                系统                On                备注
                openjdk6 64-Bit                Linux                travis-ci
                oraclejdk7 64-Bit                Linux                travis-ci
                openjdk7 64-Bit                Linux                travis-ci
                oraclejdk8 64-Bit                Linux                travis-ci
                applejdk6 64-Bit                Mac                个人Macjdk6及以下,Apple提供了自己的Java版本
                oraclejdk7 64-Bit                Mac                个人Mac                从jdk7开始,Mac jdk直接在Oracle下载。
                oraclejdk8 64-Bit                Mac                个人Mac
                oraclejdk7 64-Bit                windows server 2012 r2                appveyor
                oraclejdk7 32-Bit                windows server 2012 r2                appveyor
                oraclejdk8 64-Bit                windows server 2012 r2                appveyor
                oraclejdk8 32-Bit                windows server 2012 r2                appveyor

PS:感谢 travis-ci 和 appveyor 免费提供了持续集成环境。

Java API Docs

Java API文档地址: http://alibaba.github.io/java-dns-cache-manipulator/apidocs

依赖

Maven示例:

<dependency>
    <groupId>com.alibaba</groupId>
    <artifactId>dns-cache-manipulator</artifactId>
    <version>1.5.0</version>
</dependency>

可以在search.maven.org查看最新的版本。

Developer Guide

如何修改JVM的DNS Cache

JVM的DNS Cache维护在类InetAddress的addressCache私有字段中,通过反射来修改, 具体参见InetAddressCacheUtil

注意修改JVM的DNS Cache的线程安全问题

JVM的DNS Cache显然是全局共用的,所以修改需要同步以保证没有并发问题。

通过查看类InetAddress的实现可以确定:通过以addressCache字段为锁的synchronized块来保证线程安全。

其中关键代码(JDK 7)如下:

/*  * Cache the given hostname and addresses.  */ private static void cacheAddresses(String hostname, InetAddress[] addresses, boolean success) {
    hostname = hostname.toLowerCase(); synchronized (addressCache) {
        cacheInitIfNeeded(); if (success) {
            addressCache.put(hostname, addresses);
        } else {
            negativeCache.put(hostname, addresses);
        }
    }
}

InetAddressCacheUtil类中对DNS Cache的读写也一致地加了以addressCache为锁的synchronized块,以保证线程安全。

需要测试不同版本JDK

本库实现使用了JDK的非公开API,不同JDK实现会不一样,即需要有兼容逻辑,并对不同版本JDK进行测试,以保证功能。

目前测试包含JDK版本参见【经过测试的JDK】一节。

相关资料

加载中

评论(0)

暂无评论

暂无资讯

暂无问答

httpclient DNS cache问题解决办法

DNS缓存在操作系统和JDK内部已经实现了吧,一般不需要再由程序介入了。 the JVM will cache the dns information for me automatically after the first query 也就是说,httpclient去抓取每...

2012/05/28 20:54
917
0
Ubuntu Server 10.04, resin 3.1.10, nginx 0.7.65 架设负载均衡网站

Ubuntu Server 10.04, resin 3.1.10, nginx-0.7.65 架设负载均衡网站 软件硬件架构 internet -> fire wall -> f5 load balancer -> router -> web servers(ubuntu + nginx + resins) -> db ...

2012/03/09 15:50
80
0
JAVA泛型详解

参考文章:1.《JAVA编程思想 第4版》 2.java泛型详解http://luckykapok918.blog.163.com/blog/static/2058650432012102341548827/ Java泛型(generics)是JDK 5中引入的一个新特性,允许在定...

2014/04/24 09:43
34
0
DNS说明

本次内容比较hardcore,非科班出身可能会有理解障碍,可以考虑不用挣扎,直接放弃。毕竟普通驾驶员是不需要理解内燃机原理和曲轴如何做功的,所谓术业有专攻也,能看完的不是同行就是真爱~ 引...

2015/05/20 19:50
204
0
EHCache 中的 CacheManager的创建方法

1. EHCache 的特点,是一个纯Java ,过程中(也可以理解成插入式)缓存实现,单独安装Ehcache ,需把ehcache-X.X.jar 和相关类库方到classpath中。如项目已安装了Hibernate ,则不需要做什么。...

2012/12/10 16:03
505
0
EHCache安装配置详解

1. EHCache 的特点,是一个纯Java ,过程中(也可以理解成插入式)缓存实现,单独安装Ehcache ,需把ehcache-X.X.jar 和相关类库方到classpath中。如项目已安装了Hibernate ,则不需要做什么。...

2011/11/02 09:56
4.5K
0
zk 迁移遇到的java DNS

地址   在实际环境中,我们可能因为各种原因比如机器过保,硬件故障等需要迁移Zookeeper集群,所以Zookeeper的地址是一个很头痛的事情。这个地址有两方面,第一个是提供给Client的地址,建...

05/16 11:58
13
0
ENHCASH分布式缓存

1. EHCache 的特点,是一个纯Java ,过程中(也可以理解成插入式)缓存实现,单独安装Ehcache ,需把ehcache-X.X.jar 和相关类库方到classpath中。如项目已安装了Hibernate ,则不需要做什么。...

2015/07/22 22:14
10
0
关于java的DNS解析IP缓存问题

java对DNS解析IP进行缓存,默认缓存超时时间为-1(在重启JVM前永久缓存), 在第一次访问某域名后将会缓存解析到的IP地址,之后直接从缓存里获得所需的信息(如IP地址),而无需再访问DNS服务...

2013/08/09 22:36
706
0

没有更多内容

加载失败,请刷新页面

返回顶部
顶部