Java学习者论坛

 找回密码
 立即注册

QQ登录

只需一步,快速开始

手机号码,快捷登录

恭喜Java学习者论坛(https://www.javaxxz.com)已经为数万Java学习者服务超过8年了!积累会员资料超过10000G+
成为本站VIP会员,下载本站10000G+会员资源,购买链接:点击进入购买VIP会员
JAVA高级面试进阶视频教程Java架构师系统进阶VIP课程

分布式高可用全栈开发微服务教程

Go语言视频零基础入门到精通

Java架构师3期(课件+源码)

Java开发全终端实战租房项目视频教程

SpringBoot2.X入门到高级使用教程

大数据培训第六期全套视频教程

深度学习(CNN RNN GAN)算法原理

Java亿级流量电商系统视频教程

互联网架构师视频教程

年薪50万Spark2.0从入门到精通

年薪50万!人工智能学习路线教程

年薪50万!大数据从入门到精通学习路线年薪50万!机器学习入门到精通视频教程
仿小米商城类app和小程序视频教程深度学习数据分析基础到实战最新黑马javaEE2.1就业课程从 0到JVM实战高手教程 MySQL入门到精通教程
查看: 462|回复: 0

[网络编程学习]Java网络编程从入门到精通(4):DNS缓存

[复制链接]
  • TA的每日心情
    开心
    2021-3-12 23:18
  • 签到天数: 2 天

    [LV.1]初来乍到

    发表于 2014-11-7 00:04:38 | 显示全部楼层 |阅读模式
    在通过DNS查 找域名的过程中,可能会经过多台中间DNS服务器才能找到指定的域名,因 此,在DNS服务器上查找域名是非常昂贵的操作。在java中为了缓解这个问题,提供了DNS缓存。当InetAddress类第一次使用某个域名(如www.csdn.net)创建InetAddress对象后,JVM就 会将这个域名和它从DNS上获得的信息(如IP地址)都保存在DNS缓存中。当下一次InetAddress类再使用这个域名时, 就直接从DNS缓存里获得所需的信息,而无需再访问DNS服务器。  
       
        DNS
        缓存在 默认时将永远保留曾经访问过的域名信息,但我们可以修改这个默认值。一般有两种方法可以修改这个默认值:
       
       
        1.
        在程序 中通过java.security.Security.setProperty
        方法设置安全属性networkaddress.cache.ttl
        的值(单位:秒)。如下面的代码将缓存超时设为10
        秒:



       
       
         
        java.security.Security.setProperty(
        "
        networkaddress.cache.ttl
        "
        ,
        10
        );
       
      
       
       
         
       

         
       
      



      2.
      设置java.security
      文件中的networkaddress.cache.negative.ttl
      属性。假设JDK
      的 安装目录是C:jdk1.6
      ,那么java.security
      文件位于c:jdk1.6jrelibsecurity
      目录中。打开这个文件,找到networkaddress.cache.ttl
      属性,并将这个属性值设为相应的缓存超时(单位:秒)。
      

          如果将networkaddress.cache.ttl
      属性值设为-1
      , 那么DNS
      缓存数据将永远不会释放。下面的代码
      演示了使用和不使用DNS
      缓存所产生效果:

      
      
       
      package
       mynet;


      import
       java.net.*;


      public
       
      class
       MyDNS
    {
         
      public
       
      static
       
      void
       main(String[] args)
      throws
       Exception
         {
             
      //
       args[0]: 本机名 args[1]:缓冲时间
      

             
      if
       (args.length
      <
      2
      )
                
      return
      ;
             java.security.Security.setProperty(
      "networkaddress.cache.ttl", args[1]);
             
      long
       time
      = System.currentTimeMillis();
             InetAddress addresses1[] = InetAddress.getAllByName(args[0]);
             System.out.println("addresses1:   "
                             + String.valueOf(System.currentTimeMillis() - time)
                             + "毫 秒"
      );
             
      for
       (InetAddress address : addresses1)
                 System.out.println(address);
             System.out.print(
      "按 任意键继续...");
             System.in.read();
             time = System.currentTimeMillis();
             InetAddress addresses2[] = InetAddress.getAllByName(args[0]);
             System.out.println("addresses2:   "
                             + String.valueOf(System.currentTimeMillis() - time)
                             + "毫 秒"
      );
             
      for
       (InetAddress address : addresses2)
                 System.out.println(address);
         }
    }

      
      
      
       
       
      

          在上面的代码中
      设置了DNS
      缓存 超时(通过args[1]参数)
      ,用户可以通过命令行参数将这个值传入MyDNS
      中。这个程序首先使用getAllByName
      建立一个InetAddress
      数组,然后通过System.in.read
      使程序暂停。当 用户等待一段时间后,可以按任意键继续,并使用同一个域名(args[0])
      再建立一个InetAddress
      数组。如果用户等待的这段时 间比DNS
      缓存超时小,那么无论情况如何变化,addresses2
      和addresses1
      数组中的元素是一样的,并且创建addresses2
      数组所花 费的时间一般为0
      毫秒(小于1
      毫秒后,Java
      无 法获得更精确的时间)。
      
      
       
       
      

         
    测试

      1
      
      

      执行如下命令 (将DNS
      缓存超时设为5
      秒):

      
      
       
      java mynet.MyDNS www.
      126
      .com
      5
      

      
      
       
       
      运行结果1
      (在5
      秒之内按任意键):
      

      
      
       
      addresses1:   344毫秒
    www
      .126
      .com/
      202.108.9.77
      
    按任意键继续...
    addresses2:  0 毫秒
    www
      .126
      .com/
      202.108.9.77
      

      
      
       
       
      运行结果2
      (在5
      秒后按任意键):
      

      
      
       
      addresses1:   344毫秒
    www
      .126
      .com/
      202.108.9.77
      
    按任意键继续...
    addresses2:  484 毫秒
    www
      .126
      .com/
      202.108.9.77
      

      
      
      

      
        在上面的测试 中可能出现两个运行结果。如果在出现“
      按任意键继续…”
      后,在5
      秒之内按 任意键继续后,就会得到运行结果1
      ,从这个结果可以看出,addresses2
      所用的时间为0
      毫 秒,也就是说,addresses2
      并未真正访问DNS
      服务器,而是直接从内存中的DNS
      缓存得到的数据。当在5
      秒后按任意键继续后,就会得到运行结果2
      ,这时,内存中的DNS
      缓存中的数据已经释放,所以addresses2
      还得再访问DNS
      服 务器,因此,addresses2
      的时间是484
      毫秒(addresses1
      和addresses2
      后面的毫秒数可能在不同的环境下的值不 一样,但一般情况下,运行结果1
      的addresses2
      的值为0
      或是一个 接近0
      的数,如5
      。运行结果2
      的addresses2
      的值一般会和addresses1
      的值很接近,或是一个远比0
      大的数,如1200
      )。


      
       
       
      

       测试
      2
      
      

      执行如下命令 (ComputerName
      为本机的计算机名,DNS
      缓存超时设为永不过期[-1]
      ):

      
      
       
      java mynet.MyDNS ComputerName -
      1
      
      
       
       
      

      运行结果(按任意键继续之前,将192.168.18.20
      删除):

      
      
       
      addresses1:   31毫秒
    myuniverse/
      192.168.18.10
      
    myuniverse/
      192.168.18.20
      
    按任意键继续...
    addresses2:   0 毫秒
    myuniverse/
      192.168.18.10
      
    myuniverse/
      192.168.18.20
      

      
      
       
          
         从上面的测试可以看出,将DNS
      缓存设为永不过期后,无论过多少时间,按任意键后,addresses2
      任然得到了两个IP
      地 址(192.168.18.10
      和192.168.18.20
      ),而且addresses2
      的时间是0
      毫秒,但在这时192.168.18.20
      已经被删除。因此可以判断,addresses2
      是从DNS
      缓存中得 到的数据。如果运行如下的命令,并在5
      秒后按任意键继续后,addresses2
      就会只剩下一个IP
      地 址(192.168.18.10
      )。
      

      
      
       
      java mynet.MyDNS ComputerName
      5
      
      
       
       
      

      如果域名在DNS
      服务器上不存在,那么客户端在进行一段时间的尝试后(平均为5
      秒),就会抛出一个UnknownHostException
      异常。为了让下一次访问这个域名时不再等待,DNS
      缓存将这个错误信息也保存了起来。也就是说,只有第一次访问错误域名时才进行5
      称左右的尝试,以后再访问这个域名时将直接抛出UnknownHostException
      异常,而无需再等待5
      秒钟,
      

      访问域名失败 的原因可能是这个域名真的不存在,也可能是因为DNS
      服务器或是其他的硬 件或软件的临时故障,因此,一般不能将这个域名错误信息一直保留。在Java
      中可以通过networkaddress.cache.negative.ttl
      属性设置保留这些信息的时间。这个属性的默认值是10
      秒。它也可以通过java.security.Security.setProperty
      方法或java.security
      文件来设置。下面的代码
      演示了networkaddress.cache.negative.ttl
      属性的用法:

      
      
       
      package
       mynet;


      import
       java.net.
      *
      ;


      public
       
      class
       MyDNS1
    {
         
      public
       
      static
       
      void
       main(String[] args)
      throws
       Exception
         {
             java.security.Security.setProperty(
      "
      networkaddress.cache.negative.ttl
      "
      ,
                            
      "
      5
      "
      );
             
      long
       time
      =
       
      0
      ;
             
      try
      
             {
                 time
      =
       System.currentTimeMillis();
                 InetAddress.getByName(
      "
      www.ppp123.com
      "
      );
             }
             
      catch
       (Exception e)
             {
                 System.out.println(
      "
      www.ppp123.com 不存在! address1:
      "
      
                                 
      +
       String.valueOf(System.currentTimeMillis()
      -
       time)
                                 
      +
       
      "
      毫 秒
      "
      );
             }
             
      //
      Thread.sleep(6000);
      //
       延迟6秒
      

             
      try
      
             {
                 time
      =
       System.currentTimeMillis();
                 InetAddress.getByName(
      "
      www.ppp123.com
      "
      );
             }
             
      catch
       (Exception e)
             {
                 System.out.println(
      "
      www.ppp123.com 不存在! address2:
      "
      
                                 
      +
       String.valueOf(System.currentTimeMillis()
      -
       time)
                                 
      +
       
      "
      毫 秒
      "
      );
             }
         }
    }

      
      

      在上面的代码 中
      将networkaddress.cache.negative.ttl
      属性值设为5
      秒。 这个程序分别测试了address1
      和address2
      访问www.ppp123.com
      (这是个不存在的域名,读者可以将其换成任何不存在的域名)后,用了多长时间抛出UnknownHostException
      异常。
      

      运行结果:
      
      
       
      www.ppp123.com不存 在! address1:  4688毫秒
    www.ppp123.com不存 在! address2:  0毫秒
       
      
      

          我们从上面的运行结果可以看出,address2
      使用了0
      毫秒就抛 出了异常,因此,可以断定address2
      是从DNS
      缓存里获得了域名www.ppp123.com
      不可访问的信息,所以就直接抛出了UnknowHostException
      异常。如果将上面代码中的延迟代码
      的注释去掉,
      那么可 能得到如下的运行结果:
      
      
       
      www.ppp123.com不存 在! address1:  4688毫秒
    www.ppp123.com不存 在! address1:  4420毫秒

      
      
      
       
      从上面的运行结果可以看出,在第6
      秒时,DNS
      缓存中 的数据已经被释放,因此,address2
      仍需要访问DNS
      服务器才能知道www.ppp123.com
      是不可访问的域名。
      

       
       
      

      在使用DNS缓存时有两点需要注意:
      

      1.
      可以根据实际情况来设置networkaddress.cache.ttl
      属性的值。一般将这个属性的值设为-1
      。但如果访问的是动态映射的域名(如使用动态域名服务将域名映射成ADSL
      的动态IP
      ),
      就可能产生IP
      地址变化后,客户端得到的还是原来的IP
      地址的情况。
      

      2.
      在设置networkaddress.cache.negative.ttl
      属性值时最好不要将它设为-1
      ,否则如果一个域名因为暂时的故障而无法访问,那么程序再次访问这个域名时,即使这个域名恢复正常,程序也无法再访问这个域名 了。除非重新运行程序。
      

      
    本文出自 “软件改变整个宇宙” 博客,请务必保留此出处http://androidguy.blog.51cto.com/974126/214814



      
      
       
       

         
       

         
       
      
    复制代码

    源码下载:http://file.javaxxz.com/2014/11/7/000437890.zip
    回复

    使用道具 举报

    您需要登录后才可以回帖 登录 | 立即注册

    本版积分规则

    QQ|手机版|Java学习者论坛 ( 声明:本站资料整理自互联网,用于Java学习者交流学习使用,对资料版权不负任何法律责任,若有侵权请及时联系客服屏蔽删除 )

    GMT+8, 2025-2-25 10:40 , Processed in 0.316884 second(s), 36 queries .

    Powered by Discuz! X3.4

    © 2001-2017 Comsenz Inc.

    快速回复 返回顶部 返回列表