Skip to content

🔍 A simple 0-dependency thread-safe lib for setting dns programmatically without touching host file, make unit/integration test portable.

License

Notifications You must be signed in to change notification settings

forcoder/java-dns-cache-manipulator

 
 

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

66 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Java Dns Cache Manipulator(DCM)

Build Status Windows Build Status Coverage Status
Maven Central GitHub release Dependency Status
GitHub issues License

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

🔧 功能

  • 设置/重置DNS(不会再去Lookup DNS
    • 可以设置单条
    • 或是通过Properties文件批量设置
  • 查看DNS Cache内容
  • 删除一条DNS Cache(即重新Lookup DNS
  • 清空DNS Cache(即所有的域名重新Lookup DNS

🎨 需求场景

  1. 一些库中写死了连接域名,需要通过修改host文件绑定才能做测试。结果是:
    • 自动持续集成的机器上一般同学是没有权限去修改host文件的,导致项目不能持续集成。
      实际上是因为这点,催生这个库的需求。 😣🔫
    • 单元测试需要每个开发都在开发机上做host绑定,增加了依赖的配置操作且繁琐重复。
  2. 一些功能需要域名作为输入参数,如使用HTTP请求的网关 或是 有域名检查限制的Web应用。
    这种情况下,让需要让一个域名连接到测试机器的IP上,或是 使用一个还不存在的域名但又不想或不能去配置DNS
  3. 在性能测试时,
    • 不去做网络的DNS LookupDNS解析消耗),这样使得压测更加关注服务器响应,压测更充分反应出实现代码的性能。
    • 可以动态修改DNS缓存,无需修改host文件和http链接等不灵活的方式。
    • 一个JVM进程可以对应一套域名绑定,相互之间不影响,可以实现多场景,多域名绑定的需求压测。
  4. 打开Java中的SecurityManager时(如在Web容器Tomcat中的Web应用),JavaDNS缺省是不会失效的。 如果域名绑定的IP变了,可以通过这个库重置DNS,作为一个临时的手段(强烈不推荐)。
    当然往往进行要先有能执行入口,比如远程调用或是jvm-ssh-groovy-shell

👥 User Guide

通过类DnsCacheManipulator设置DNS

直接设置

DnsCacheManipulator.setDnsCache("www.hello-world.com", "192.168.10.113");

// 之后Java代码中使用到域名都会解析成上面指定的IP。
// 下面是一个简单获取域名对应的IP,演示一下:

String ip = InetAddress.getByName("www.hello-world.com").getHostAddress();
// ip = "192.168.10.113"

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

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

使用方式如下:

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

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

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

DnsCacheManipulator.loadDnsCacheConfig();

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

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

清空JVM DNS Cache

DnsCacheManipulator.clearDnsCache();

查看JVM DNS Cache

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

更多详细功能参见类DnsCacheManipulator的文档说明。

🔌 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.2.0</version>
</dependency>

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

🎓 Developer Guide

如何修改JVMDNS Cache

JVMDNS Cache维护在类InetAddressaddressCache私有字段中,通过反射来修改, 具体参见InetAddressCacheUtil

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

JVMDNS 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块,以保证线程安全。

📚 相关资料

About

🔍 A simple 0-dependency thread-safe lib for setting dns programmatically without touching host file, make unit/integration test portable.

Resources

License

Stars

Watchers

Forks

Packages

No packages published

Languages

  • Java 94.0%
  • Shell 5.6%
  • HTML 0.4%