zoukankan      html  css  js  c++  java
  • Linux内网环境DNS修改域名指向,JAVA应用程序能否实时切换的问题总结

    公司内网环境中许多调用资源(数据库、web接口等)都是通过内网DNS服务来进行域名-IP的映射。

    但经常出现DNS映射修改完毕后,应用中连接的资源迟迟没有变更。

    以前一直笼统的认为是linux的dns缓存导致,今天做了一次完整的分析,结果如下:

    1、Linux系统的本地DNS的缓存

    CentOS系统本身并不包含DNS的缓存机制,除非安装并启动了nscd服务(name server cache daemon)。

    nscd服务启动后会默认为本地的所有dns解析做一层缓存,过期时间默认为3600秒,重启应用程序也不会重置nscd的缓存,除非用/etc/init.d/nscd reload,强制刷新nscd缓存。

    开启nscd服务可以大大降低应用程序请求DNS服务的频率,同时一定程度上可以对DNS服务的故障有一定容错。但缺点非常明显,DNS服务的映射改变无法实时的被应用程序感知,每次修改映射后都必须在所有客户端机器reload nscd。

    以上结论通过DNS服务日志得到验证。

    2、JVM虚拟机的本地DNS缓存

    实现在java.net.InetAddress的一个简单的DNS缓存机制,以前被误认为是Linux的DNS缓存,jdk6/7中默认为缓存30秒。

    缓存范围为JVM虚拟机进程,也就是说同一个JVM进程中,30秒内只会为一个域名请求DNS服务器一次,可以大大降低应用程序对DNS解析的网络损耗和对DNS服务产生的压力。

    以上结论通过JAVA测试程序和DNS服务日志得到验证。

    3、长连接的处理(数据库链接、redis连接、zookeeper、activeMQ连接等)

    根据1、2两点结论,当内网DNS服务某一个域名映射修改后,应用程序最多在30秒内就会响应该变化。但实际确不是如此,原因就是很多资源是“长连接”方式。

    比如数据库连接池这种就是典型的长连接,为了保证连接池效率,我们也不能把单个连接的有效期设的太短。这就导致了这类长连接无法快速响应DNS服务器的映射改变。

    解决办法只有一个:DNS服务器的映射变更后,需要对应用程序做重启,以便让长连接按照新的DNS映射来进行建立。

    以上结论通过JAVA测试程序和DNS服务日志得到验证。

    饶了一圈,最后还是回到原点:

    为了保证应用程序里的这些长连接资源能够及时响应DNS映射的改变,目前还是得靠重启应用来解决。

  • 相关阅读:
    Xml 映射文件中,除了常见的 select|insert|updae|delete 标签之外,还有哪些标签?
    zookeeper 是如何保证事务的顺序一致性的?
    什么是 Callable 和 Future?
    MyBatis 实现一对一有几种方式?具体怎么操作的?
    Zookeeper 对节点的 watch监听通知是永久的吗?为什么 不是永久的?
    合同测试你懂什么?
    查看各类环境变量用什么命令?
    我们如何进行跨功能测试?
    怎么查看系统支持的所有信号?
    Mybatis 是否支持延迟加载?如果支持,它的实现原理是什么?
  • 原文地址:https://www.cnblogs.com/baibaluo/p/4621064.html
Copyright © 2011-2022 走看看