zoukankan      html  css  js  c++  java
  • crawler_JVM_DNS_在爬虫中的应用

    DNS解析:即由域名 经过dns解析,跳转到真正服务器的地址,这个重复解析的耗时占请求很大比例。 在设计爬虫时比较细粒度的控制下,需要考虑dns解析。 jdk从1.5往后对dns缓存有默认设置,

    详见jdk源码,不过有部分细节还是需要自己去处理的。

    JAVA本身对DNS的缓存时间是多久?

    对于爬虫DNS解析耗时的疑问,第一反应Google之,大致有两种说法:
    第1种:默认情况下networkaddress.cache.ttl=-1,代表永久缓存(配置文件路径: JAVA_HOME/jre/lib/security/java.security),就是在应用启动之后第一次DNS 解析成功的结果会一直cache到应用停止。显然在域名对应的IP有变更的时候,如果不重启应用就会造成故障。有部分同事以前也做过相关测试,认同这种说法。

    第2种:jdk1.5和1.5之前的版本默认DNS 缓存时间是永久缓存,jdk 1.6以后与security manager策略有关,如果没有启用security manager ,默认DNS 缓存时间30秒。策略配置文件:JAVA_HOME/jre/lib/security/java.policy

    测试code

     1 import java.net.InetAddress;
     2 
     3 /**
     4  * @declare: DNS缓存研究 <br>
     5  * @author: cphmvp
     6  * @version: 1.0
     7  * @date: 2014-3-17下午5:37:07
     8  */
     9 public class MyDNS {
    10     // jvm dns缓存研究
    11     public static void main(String[] args) throws Exception {
    12         String hostName = "www.baidu.com";
    13         String cacheTime = "10";
    14         java.security.Security.setProperty("networkaddress.cache.ttl",
    15                 cacheTime);
    16         for (int i = 0; i < 100; i++) {
    17             long time = System.currentTimeMillis();
    18             InetAddress addresses1[] = InetAddress.getAllByName(hostName);
    19             System.out.println("addresses1:   "
    20                     + String.valueOf(System.currentTimeMillis() - time) + "毫秒");
    21             for (InetAddress address : addresses1)
    22                 System.out.println(address);
    23         }
    24         // 当缓存时间为 0时,在一百次访问www.baidu.com 都有耗时情况【未考虑操作系统缓存】
    25         // 当缓存时间为 10时,在一百次访问www.baidu.com ,只有第一次耗时,后99次不消耗dns查找时间
    26         // 如果不设置 networkaddress.cache.ttl,默认为-1
    27         // ,只有第一次耗时,后99次不消耗dns查找时间【后多少次都不在耗时,直至JVM重启】
    28     }
    29 }

    默认JVM会缓存每一次DNS的查询结果,并且使缓存结果永远有效,直到你对该JVM重启为止。有时候业务需要系统能对域名切换及时而自动进行切换。这时候你就需要禁用或调整JVM的DNS缓存机制。

    在独立运行程序中(非容器环境),可以在应用启动的时候通过以下代码完成:
             //设置解析成功的域名记录JVM中缓存的有效时间,JVM默认是永远有效,这样一来域名IP重定向必须重启JVM,这里修改为3秒钟有效,0表示禁止缓存,-1表示永远有效
            Security.setProperty("networkaddress.cache.ttl", "3");
             //设置解析失败的域名记录JVM中缓存的有效时间,JVM默认是10秒,0表示禁止缓存,-1表示永远有效
            Security.setProperty("networkaddress.cache.negative.ttl", "3");

    代码中设置“networkaddress.cache.ttl”值的方式只适用于非容器环境,当应用部署与resin等容器中时该设置控制不了JVM的行为。可行的办法是通过在容器的启动参数中设置JDK系统变量“sun.net.inetaddr.ttl“或“sun.net.inetaddr.negative.ttl”,该参数跟“networkaddress.cache.ttl”和“networkaddress.cache.negative.ttl”的值定义一样,只是一个用于命令行,一个用于程序内部。具体操作方法:
    修改httpd.sh,在"args="选项添加参数,如:-Dsun.net.inetaddr.ttl=0
     
    如果非Resin容器的Java应用中同时配置了命令参数“sun.net.inetaddr.ttl”和Security属性“networkaddress.cache.ttl”,那么会以Security属性的设置为准。
    结论:
    方法一: 设置jvm参数,制定缓存有效期
    方法二:硬编码 ,java.security.Security.setProperty("networkaddress.cache.ttl",cacheTime); 设置有效期。

    一般情况下我们不需要完全取消JVM的DNS缓存,只需要调小有效时间,经过一些测试发现一下结论:
    1)1个域名对应一个IP和一个域名对应12个IP,DNS查询响应时间差别极少,后者占用cpu稍高一点点;
    2)在高并发时,不做DNS缓存时的CPU耗用比做了3s缓存的CPU耗用要高3/4倍,实时DNS请求相当耗用CPU;
    3)3s和30s缓存有效时间对dns查询响应时间的影响差别不大,cpu内存占用都比较接近;
    4)建议使用3秒缓存,兼顾运维和性能,对于不常改动指向ip的域名,可以设置时间更长 ,以提高性能。
     
  • 相关阅读:
    ASP.NET2.0中用Gridview控件操作数据
    有关petShop的几篇文章
    用多活动结果集优化ADO.NET2.0数据连接
    设计数据层组件并在层间传递数据
    google的语法?
    PHP导出Excel方法
    header ContentType类型
    40条优化php代码的小实例
    strstr 不错的技巧
    PHP 截取字符串专题
  • 原文地址:https://www.cnblogs.com/cphmvp/p/3605580.html
Copyright © 2011-2022 走看看