博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Netty Client使用域名重连的问题
阅读量:6564 次
发布时间:2019-06-24

本文共 3120 字,大约阅读时间需要 10 分钟。

hot3.png

DNS解析过程

  1. 在浏览器中输入www.baidu.com域名,操作系统会先检查自己本地的hosts文件是否有这个网址映射关系,如果有,就先调用这个IP地址映射,完成域名解析。
  2. 如果hosts里没有这个域名的映射,则查找本地DNS解析器缓存,是否有这个网址映射关系,如果有,直接返回,完成域名解析。
  3. 如果hosts与本地DNS解析器缓存都没有相应的网址映射关系,首先会找TCP/IP参数中设置的首选DNS服务器,在此我们叫它本地DNS服务器,此服务器收到查询时,如果要查询的域名,包含在本地配置区域资源中,则返回解析结果给客户机,完成域名解析,此解析具有权威性。
  4. 如果要查询的域名,不由本地DNS服务器区域解析,但该DNS服务器已缓存了此网址映射关系,则调用这个IP地址映射,完成域名解析,此解析不具有权威性。
  5. 如果本地DNS服务器本地区域文件与缓存解析都失效,则根据本地DNS服务器的设置(没有设置转发器)进行查询,如果未用转发模式,本地DNS就把请求发至13台根DNS,根DNS服务器收到请求后会判断这个域名(.com)是谁来授权管理,并会返回一个负责该顶级域名服务器的一个IP。本地DNS服务器收到IP信息后,将会联系负责 .com域的这台服务器。这台负责 .com域的服务器收到请求后,如果自己无法解析,它就会找一个管理 .com域的下一级DNS服务器地址(baidu.com)给本地DNS服务器。当本地DNS服务器收到这个地址后,就会找baidu.com域服务器,重复上面的动作进行查询,直至找到www.baidu.com主机。
  6. 如果用的是转发模式(设置转发器),此DNS服务器就会把请求转发至上一级ISP DNS服务器,由上一级服务器进行解析,上一级服务器如果不能解析,或找根DNS或把转请求转至上上级,以此循环。不管是本地DNS服务器用是是转发,还是根提示,最后都是把结果返回给本地DNS服务器,由此DNS服务器再返回给客户机。 注:从客户端到本地DNS服务器是属于递归查询,而DNS服务器之间就是迭代查询。

Linux对DNS的支持

Linux操作系统本身没有对DNS缓存的支持(作为客户端时),如果为了提升性能,可以使用nscd提供DNS缓存的支持。

Java对DNS缓存的支持

Java语言对DNS缓存的支持

java.net.InetAddress使用DNSNameService正向通过主机名获得IP地址,或者通过IP地址反向解析得到主机名。 java.net.InetAddress提供了DNS解析成功的域名记录的缓存,解析失败的域名记录的缓存。 解析成功的域名记录的缓存的缓存有效期是永久的,解析失败的域名记录的缓存的有效期是10s。 这样做的目的是提升性能,以及防止DNS欺骗攻击。 当编程时,需要特别注意,一旦连接断开,需要注意重新 new 一个 InetAddress 对象,并进行重连。

清除InetAddress缓存的方法

public static void clearCache() throws NoSuchFieldException, IllegalAccessException {      //修改缓存数据开始      Class clazz = java.net.InetAddress.class;      final Field cacheField = clazz.getDeclaredField("addressCache");      cacheField.setAccessible(true);      final Object obj = cacheField.get(clazz);      Class cacheClazz = obj.getClass();      final Field cachePolicyField = cacheClazz.getDeclaredField("type");      final Field cacheMapField = cacheClazz.getDeclaredField("cache");      cachePolicyField.setAccessible(true);      cacheMapField.setAccessible(true);      final Map cacheMap = (Map)cacheMapField.get(obj);      System.out.println(cacheMap);      cacheMap.remove("www.baidu.com");  //清除指定的域名缓存}

JVM对DNS缓存的支持

JVM缓存了DNS的解析结果,同样提供两种记录(解析成功和解析失败)的缓存,但是相关的信息有JVM维护和管理。 不过sun提供了两种方式对JVM的DNS成功和失败缓存的有效期进行设置。

java.security.Security方式

  • 修改jvm的配置java.security

jre/lib/security/java.security 下的 networkaddress.cache.ttl 解析成功的缓存有效期,默认永久有效。

jre/lib/security/java.security 下的 networkaddress.cache.negative.ttl 解析失败的缓存有效期,默认10秒。

  • java代码设置

java.security.Security.setProperty("networkaddress.cache.ttl", "3"); java.security.Security.setProperty("networkaddress.cache.negative.ttl", "1");

任意负值:缓存永久有效0:不做缓存正值:缓存多久(单位为秒)

java.lang.System方式

  • java代码设置

System.setProperty("sun.net.inetaddr.ttl", "3"); System.setProperty("sun.net.inetaddr.negative.ttl", "1");

  • 添加启动参数

-Dsun.net.inetaddr.ttl=3 -Dsun.net.inetaddr.negative.ttl=1

Netty对DNS缓存的支持

在Netty4.0版本之前是没有对DNS的支持的,在4.0之后加入了DNS的。

但是在使用netty时,需要对使用域名进行连接的应用而言,需要特别注意对重连的考虑。 netty client使用InetSocketAddress指定服务端地址,而InetSocketAddress使用InetAddress进行域名的解析和缓存解析结果。这里要特别消息,InetAddress使用DNSNameService进行解析的过程,受networkAddress.cache.ttl影响,但是解析后的结果InetSocketAddress,是不会再被刷新了,除非你自己去刷新。并且nio connect的时候使用的是InetSokcetAddress解析后的ip建立连接。

nio connect

因此当使用域名的情况下,当IP进行了切换导致连接断开时,需要重新设置bootstrap的remoteAddress属性,否则无法进行IP的切换。

参考资料

转载于:https://my.oschina.net/u/583362/blog/539709

你可能感兴趣的文章
第七次课程作业
查看>>
C++ 文本查询2.0(逻辑查询)
查看>>
Objective-C学习总结-13协议1
查看>>
web学习方向
查看>>
A*算法实现
查看>>
第一周 从C走进C++ 002 命令行参数
查看>>
【java】itext pdf 分页
查看>>
看看这个电脑的配置
查看>>
[转]【NoSQL】NoSQL入门级资料整理(CAP原理、最终一致性)
查看>>
RequireJS进阶(二)
查看>>
我设计的网站的分布式架构
查看>>
linux extract rar files
查看>>
Knockout.Js官网学习(监控属性Observables)
查看>>
ORA-12514: TNS: 监听程序当前无法识别连接描述符中请求的服务解决
查看>>
azure之MSSQL服务性能测试
查看>>
Android BitmapFactory.Options
查看>>
前端构建:Less入了个门
查看>>
phonegap(cordova) 自己定义插件代码篇(三)----支付宝支付工具整合
查看>>
linux 批量进行:解压缩某一类压缩文件类型的文件
查看>>
激活modelsim se 10.4 时运行patch_dll.bat不能生成TXT
查看>>