Java如何自定义DNS解析器
本篇内容介绍了"Java如何自定义DNS解析器"的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能够学有所成!
前言:
最近终于用上了高性能的测试机(54C96G * 3),相较之前的单机性能提升了三倍,数量提升了三倍,更关键的宽带提单机升了30倍不止,总体讲提升了100多倍,这下再也不用担心单机压力机瓶颈,直接原地起飞。
不过没高兴5分钟,我发现接口居然请求不通,经过一阵拨乱反正终于找到原因:域名无法解析,IP无法直接访问。
自然而然,解决方案呼之欲出:自定义Java DNS解析器。
经过同事指点、资料搜索和探索实践。终于锁定了两个核心类:org.apache.http.impl.conn.InMemoryDnsResolver
和org.apache.http.impl.conn.SystemDefaultDnsResolver
,下面我会演示一下这两个类的使用实践,其中主要区别还是在负载均衡的实现上,这个有空再分享。
1.InMemoryDnsResolver
这个类使用比较简单,先写一个Demo,实现一个简单的域名解析。
/** * 重写Java自定义DNS解析器,非负载均衡 * * @return */ private static DnsResolver getDnsResolver2() { InMemoryDnsResolver dnsResolver = new InMemoryDnsResolver(); try { dnsResolver.add("fun.tester", InetAddress.getByName("127.0.0.1")); } catch (Exception e) { e.printStackTrace(); } return dnsResolver; }
这样我们就可以把fun.tester解析到127.0.0.1上了,后面我会进行一个简单的测试。
2.SystemDefaultDnsResolver
这个看名字是系统默认DNS解析器,但默认在哪,我也没看出来,唯一可以查到的引用就是异步线程池管理器使用
org.apache.http.impl.nio.conn.PoolingNHttpClientConnectionManager#PoolingNHttpClientConnectionManager(org.apache.http.nio.reactor.ConnectingIOReactor, org.apache.http.nio.conn.NHttpConnectionFactory
, org.apache.http.config.Registry , org.apache.http.conn.SchemePortResolver, org.apache.http.conn.DnsResolver, long, java.util.concurrent.TimeUnit),
接下来我们看这个Demo
/** * 重写Java自定义DNS解析器,负载均衡 * * @return */ private static DnsResolver getDnsResolver() { return new SystemDefaultDnsResolver() { @Override public InetAddress[] resolve(final String host) throws UnknownHostException { if (host.equalsIgnoreCase("fun.tester")) { return new InetAddress[]{InetAddress.getByName("127.0.0.1")}; } else { return super.resolve(host); } } }; }
3.自定义DnsResolver
通过源码可以看出,两个实现类都是通过实现org.apache.http.conn.DnsResolver
这个接口中org.apache.http.conn.DnsResolver#resolve
方法。我们自己可以完全自己实现。
/** * 自定义本地DNS解析器实现 * * @return */ private static DnsResolver getDnsResolver3() { return new DnsResolver() { @Override public InetAddress[] resolve(final String host) throws UnknownHostException { if (host.equalsIgnoreCase("fun.tester")) { return new InetAddress[]{InetAddress.getByName("127.0.0.1")}; } else { return InetAddress.getAllByName(host); } } }; }
仔细看不难发现,其实就是代码缝合怪。
4.连接池管理器
下面分享一下如何使用自定义的org.apache.http.conn.DnsResolver
,就是在创建连接池管理器的时候设置一下就可以。
5.测试
首先我在本地起一个HTTP服务,端口12345,非常简单。代码如下:
static void main(String[] args) { def util = new ArgsUtil(args) def server = getServerNoLog(util.getIntOrdefault(0, 12345)) server.response("Have Fun ~ Tester !") def run = run(server) waitForKey("fan") run.stop() }
然后我准备一个测试脚本:
public static void main(String[] args) { String url = "http://fun.tester:12345/" def get = getHttpGet(url) def funtester = { fun { getHttpResponse(get) } } 10.times { funtester() } }
控制台日志输出:
INFO-> 27.214 F-1 请求uri:http://fun.tester:12345/ , 耗时:304 ms , HTTPcode: 200
INFO-> 27.214 F-4 请求uri:http://fun.tester:12345/ , 耗时:304 ms , HTTPcode: 200
INFO-> 27.214 F-10 请求uri:http://fun.tester:12345/ , 耗时:305 ms , HTTPcode: 200
INFO-> 27.214 F-5 请求uri:http://fun.tester:12345/ , 耗时:305 ms , HTTPcode: 200
INFO-> 27.214 F-2 请求uri:http://fun.tester:12345/ , 耗时:305 ms , HTTPcode: 200
INFO-> 27.214 F-8 请求uri:http://fun.tester:12345/ , 耗时:305 ms , HTTPcode: 200
INFO-> 27.214 F-3 请求uri:http://fun.tester:12345/ , 耗时:305 ms , HTTPcode: 200
INFO-> 27.214 F-7 请求uri:http://fun.tester:12345/ , 耗时:305 ms , HTTPcode: 200
INFO-> 27.214 F-6 请求uri:http://fun.tester:12345/ , 耗时:305 ms , HTTPcode: 200
INFO-> 27.214 F-9 请求uri:http://fun.tester:12345/ , 耗时:305 ms , HTTPcode: 200
"Java如何自定义DNS解析器"的内容就介绍到这里了,感谢大家的阅读。如果想了解更多行业相关的知识可以关注网站,小编将为大家输出更多高质量的实用文章!