赞
踩
主要是通过工具修改
https://github.com/alibaba/java-dns-cache-manipulator/tree/master/library
简单说就是下载一个工具, 然后用工具中的方法就可以动态添加hostname和ip映射
jar包下载地址
https://mvnrepository.com/artifact/com.alibaba/dns-cache-manipulator
使用方法添加即可:
DnsCacheManipulator.setDnsCache("www.hello.com", "192.168.1.1");
这是最简单的使用方法, 更多使用方法见下文.
? 用编码的方式设置/查看JVM
的DNS
(实际上设置的是DNS Cache
),支持JDK 6+
,支持IPv6
。
DNS
(不会再去Lookup DNS
)
Properties
文件批量设置DNS Cache
(即所有的域名重新Lookup DNS
)DNS Cache
(即重新Lookup DNS
)DNS Cache
内容JVM
缺省的DNS
的缓存时间host
文件绑定才能做测试。结果是:
host
文件的,导致项目不能持续集成。host
绑定,增加了依赖的配置操作且繁琐重复。HTTP
请求的网关 或是 有域名检查限制的Web
应用。IP
上,或是 使用一个还不存在的域名但又不想或不能去配置DNS
。DNS Lookup
(DNS
解析消耗),这样使得压测更加关注服务器响应,压测更充分反应出实现代码的性能。DNS
缓存,无需修改host
文件和http
链接等不灵活的方式。JVM
进程可以对应一套域名绑定,相互之间不影响,可以实现多场景,多域名绑定的需求压测。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
)。通过类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" // 可以设置多个IP DnsCacheManipulator.setDnsCache("www.hello-world.com", "192.168.2.1", "192.168.2.2"); String ipHw = InetAddress.getByName("www.hello-world.com").getHostAddress(); // ipHw = 192.168.2.1 ,读到第一个IP InetAddress[] allIps = InetAddress.getAllByName("www.hello-world.com"); // 上面读到设置的多个IP // 设置失效时间,单元毫秒 DnsCacheManipulator.setDnsCache(3600 * 1000, "www.hello-hell.com", "192.168.1.1", "192.168.1.2");
dns-cache.properties
文件批量配置在代码测试中,会期望把域名绑定写在配置文件。
使用方式如下:
在ClassPath
上,提供文件dns-cache.properties
:
# 配置格式: # <host> = <ip> www.hello-world.com=192.168.1.1 # 支持设置多个IP,用逗号分隔 www.foo.com=192.168.1.2,192.168.1.3 # 支持IPv6 www.bar.com=1234:5678:0:0:0:0:0:200e
注:
dns-cache.properties
是缺省文件名,可以通过JVM
的-D
选项dcm.config.filename
修改使用的配置文件名,如-Ddcm.config.filename=my-dns-cache.properties
。
然后通过下面的一行代码完成批量设置:
DnsCacheManipulator.loadDnsCacheConfig();
在单元测试中,往往会写在测试类的setUp
方法中,如:
@BeforeClass public static void beforeClass() throws Exception { DnsCacheManipulator.loadDnsCacheConfig(); }
JVM DNS Cache
DnsCacheManipulator.clearDnsCache();
DNS Cache
即重新Lookup DNS
。
DnsCacheManipulator.removeDnsCache("aliyun.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.aliyun.com"); client.executeMethod(m1); String content = m1.getResponseBodyAsString(); // 设置DNS,绑定到自己的机器 DnsCacheManipulator.setDnsCache("www.aliyun.com", "192.168.1.1"); // 重新执行m1,仍然是老结果 client.executeMethod(m1); String content = m1.getResponseBodyAsString(); // 重新创建GetMethod,才能得到自己机器上的结果 GetMethod m2 = new GetMethod("http://www.aliyun.com"); client.executeMethod(m2); content = m2.getResponseBodyAsString();
参见类DnsCacheManipulator
的文档说明。
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.1</version> </dependency>
可以在search.maven.org查看最新的版本。
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 | 个人Mac | jdk6由Apple提供,下载地址。 |
oraclejdk7 64-Bit | Mac | 个人Mac | 从jdk7开始,Mac jdk直接在Oracle 下载。 |
oraclejdk8 64-Bit | Mac | 个人Mac | |
oraclejdk6 64-Bit | windows server 2012 r2 | appveyor | |
oraclejdk6 32-Bit | windows server 2012 r2 | appveyor | |
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 免费提供了持续集成环境。
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
】一节。
javahost
项目, 该项目的使用文档。Java DNS Cache
的解法来自该项目。刚开始在持续集成项目中碰到host
绑定的问题时,也是使用该项目来解决的 ?InetAddress
的源代码:
JDK 6
的InetAddress
JDK 7
的InetAddress
JDK 8
的InetAddress
JVM Networking Properties
- java docs
java dns
解析缓存之源码解析,写得很完整,源码解析。给出值得注意的结论:
Java
中的SecurityManager
,DNS
缓存将不会失效。DNS
解析缺省缓存30秒,不可访问的DNS
解析缺省缓存10秒。jvm dns cache
(域名缓存时间),给出“对于多条A记录是采用什么策略返回IP
”的结论:
IP
永远是缓存中全部A记录的第一条,并没有轮循之类的策略。dig www.google.com
测试可见),所以缓存中的数据顺序也变了,取到的IP
也变化。JAVA
反射修改JDK 1.6
当中DNS
缓存内容,给出了设置DNS
缓存在性能测试下使用的场景。HttpClient
需要重新创建GetMethod
/PostMethod
对象以使设置DNS
生效问题。Java DNS
FAQ
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。