三种Java自定义DNS解析器方法与实践

网友投稿 314 2022-08-26


三种Java自定义DNS解析器方法与实践

目录1.InMemoryDnsResolver2.SystemDefaultDnsResolver3.自定义DnsResolver4.连接池管理器5.测试

前言:

最近终于用上了高性能的测试机(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 DnsResolvTNXXAoxer 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: 200INFO-> 27.214 F-4  请求uri:http://fun.tester:12345/ , 耗时:304 ms , HTTPcode: 200INFO-> 27.214 F-10 请求uri:http://fun.tester:12345/ , 耗时:305 ms , HTTPcode: 200INFO-> 27.214 F-5  请求uri:http://fun.tester:12345/ , 耗时:305 ms , HTTPcode: 200INFO-> 27.214 F-2  请求uri:http://fun.tester:12345/ , 耗时:305 ms , HTTPcode: 200INFO-> 27.214 F-8  请求uri:http://fun.tester:12345/ , 耗时:305 ms , HTTPcode: 200INFO-> 27.214 F-3  请求uri:http://fun.tester:12345/ , 耗时:305 ms , HTTPcode: 200INFO-> 27.214 F-7  请求uri:http://fun.tester:12345/ , 耗时:305 ms , HTTPcode: 200INFO-> 27.214 F-6  请求uri:http://fun.tester:12345/ , 耗时:305 ms , HTTPcode: 200INFO-> 27.214 F-9  请求uri:http://fun.tester:12345/ , 耗时:305 ms , HTTPcode: 200

三种实现方式控制台输出大同小异,都能满足我们的需求,当然仅仅是功能测试场景下。下期会结合源码分析如何实现负载均衡。


版权声明:本文内容由网络用户投稿,版权归原作者所有,本站不拥有其著作权,亦不承担相应法律责任。如果您发现本站中有涉嫌抄袭或描述失实的内容,请联系我们jiasou666@gmail.com 处理,核实后本网站将在24小时内删除侵权内容。

上一篇:'scrapyd-deploy' 不是内部或外部命令,也不是可运行的程序'scrapyd-deploy' 不是内部或外部命令,
下一篇:pytest-xdist之其他用法:dist模式、运行方式、配置文件(pytest-xdist分布式环境搭建)
相关文章

 发表评论

暂时没有评论,来抢沙发吧~