本博客属原创文章,欢迎转载!转载请务必注明出处:http://guoyunsky.iteye.com/blog/650694

本博客已迁移到本人独立博客: http://www.yun5u.com/

欢迎加入Heritrix群(QQ):109148319,10447185  , Lucene/Solr群(QQ) :  118972724

CrawlController的确是Heritrix的大脑,在Heritrix中拥有无上的权利!可以控制Heritrix的启动、暂停、停止,也定时进行数据统计、数据汇报和文件管理。同时CrawlController也基本上贯穿整个Heritrix代码,和CrawlURI一样。同时CrawlController纯代码页进2000行,下面就先介绍里面的属性和主要方法,同时对一些灵活用法也加以介绍:

 1.属性:

  1. //状态,Checkpoinging:表示正在备份
  2. private static final Object CHECKPOINTING = "CHECKPOINTING".intern();
  3. //状态,FINISHED:表示抓取结束
  4. private static final Object FINISHED = "FINISHED".intern();
  5. //状态,NASCENT:表示正在生成一个JOB
  6. private static final Object NASCENT = "NASCENT".intern();
  7. //状态,PAUSED:表示暂停结束,该状态Heritrix正暂停任何抓取
  8. private static final Object PAUSED = "PAUSED".intern();
  9. //状态,PAUSING:表示正在暂停,传达一个暂停命令到每一个线程暂停中间需要时间
  10. private static final Object PAUSING = "PAUSING".intern();
  11. //状态,PREPARING:表示抓取结束
  12. private static final Object PREPARING = "PREPARING".intern();
  13. //状态,RUNNING:表示正在运行
  14. private static final Object RUNNING = "RUNNING".intern();
  15. //状态,STARTED:表示已经启动
  16. private static final Object STARTED = "STARTED".intern();
  17. //状态,STOPPING:表示正在停止,传达一个停止命令到每一个线程暂停中间需要时间
  18. private static final Object STOPPING = "STOPPING".intern();
  19. //当前类的日志管理器
  20. private final static Logger LOGGER = Logger.getLogger(CrawlController.class
  21. .getName());
  22. // 活动的日志文件名后缀
  23. public static final String CURRENT_LOG_SUFFIX = ".log";
  24. // 日志crawl.log.txt的文件名
  25. private static final String LOGNAME_CRAWL = "crawl";
  26. // 日志local-errors.log.txt的文件名
  27. private static final String LOGNAME_LOCAL_ERRORS = "local-errors";
  28. // 日志progress-statistics.log.txt的文件名
  29. private static final String LOGNAME_PROGRESS_STATISTICS = "progress-statistics";
  30. // runtime-errors.txt的文件名
  31. private static final String LOGNAME_RUNTIME_ERRORS = "runtime-errors";
  32. // 日志uri-errors.txt的文件名
  33. private static final String LOGNAME_URI_ERRORS = "uri-errors";
  34. // 日志manifest-report的文件名前缀
  35. public final static String MANIFEST_REPORT = "manifest";
  36. //processors-report.txt的文件名前缀
  37. public final static String PROCESSORS_REPORT = "processors";
  38. // crawl-manifest日志文件中中配置文件标签缩写
  39. public static final char MANIFEST_CONFIG_FILE = 'C';
  40. // crawl-manifest日志文件中中日志文件标签缩写
  41. public static final char MANIFEST_LOG_FILE = 'L';
  42. // crawl-manifest日志文件中中报告文件标签缩写
  43. public static final char MANIFEST_REPORT_FILE = 'R';
  44. //报告文件名数组
  45. protected final static String[] REPORTS = { PROCESSORS_REPORT,
  46. MANIFEST_REPORT };
  47. //应急内存,当内存不够时Heritrix会释放这个内存去做一些紧急动作如数据备份
  48. private static final int RESERVE_BLOCK_SIZE = 6 * 2 ^ 20; // 6MB
  49. private static final int RESERVE_BLOCKS = 1;
  50. //BDB数据库,Heritrix自己封装
  51. private transient EnhancedEnvironment bdbEnvironment = null;
  52. //用于Checkpoint备份,存储需要备份的数据
  53. private transient Map<String, CachedBdbMap<?, ?>> bigmaps = null;
  54. //备份器
  55. private Checkpointer checkpointer;
  56. //备份对象
  57. private transient Checkpoint checkpointRecover = null;
  58. //备份目录
  59. private transient File checkpointsDisk;
  60. //整个Heritrix目录
  61. private transient File disk;
  62. //日志文件目录
  63. private transient File logsDisk;
  64. //scratch文件
  65. private transient File scratchDisk;
  66. //BDB数据库文件
  67. private transient File stateDisk;
  68. //日志处理器跟文件处理器关联
  69. transient private Map<Logger, FileHandler> fileHandlers;
  70. //调度器
  71. private transient Frontier frontier;
  72. // 日志处理器,关联local-errors.log
  73. public transient Logger localErrors;
  74. // 日志处理器,关联 progress-statistics.log
  75. private transient Logger progressStats;
  76. //日志处理器,关联报告文件
  77. public transient Logger reports;
  78. // 日志处理器,关联runtime-errors.log
  79. public transient Logger runtimeErrors;
  80. // 日志处理器,关联uri-Errors.log
  81. public transient Logger uriErrors;
  82. // 日志处理器,关联crawl.log
  83. public transient Logger uriProcessing;
  84. //记录Hertrix创建的日志文件名
  85. private StringBuffer manifest;
  86. //最大字节数,来源于配置文件
  87. private long maxBytes; //
  88. //抓取限制, 最大文档数,来源于配置文件
  89. private long maxDocument;
  90. // 抓取限制,最大时间,来源于配置文件
  91. private long maxTime;
  92. //管理order.xml
  93. private transient CrawlOrder order;
  94. //处理器链
  95. private transient ProcessorChainList processorChains;
  96. //事件监听器,比如正在运行、停止
  97. private transient List<CrawlStatusListener> registeredCrawlStatusListeners = Collections
  98. .synchronizedList(new ArrayList<CrawlStatusListener>());
  99. //抓取状态监听器,这里监听哪些URl被忽略,哪些URL抓取失败等
  100. private transient CrawlURIDispositionListener registeredCrawlURIDispositionListener;
  101. //抓取状态监听器数据
  102. protected transient ArrayList<CrawlURIDispositionListener> registeredCrawlURIDispositionListeners;
  103. // 应急储备内存
  104. private transient LinkedList<char[]> reserveMemory;
  105. //抓取范围管理
  106. private transient CrawlScope scope;
  107. // CrawlServer和CrawlHost的缓存
  108. private transient ServerCache serverCache;
  109. //配置文件,如order.xml
  110. private transient SettingsHandler settingsHandler;
  111. //Heritrix状态,表示已经存在
  112. private transient String sExit;
  113. // 锁,控制同时只能一个线程运行使用本类
  114. private transient ReentrantLock singleThreadLock = null;
  115. //是否是单线程模式
  116. private volatile transient boolean singleThreadMode = false;
  117. // 表示当前爬虫状态,新生的
  118. transient private Object state = NASCENT;
  119. // 统计跟踪器
  120. protected StatisticsTracking statistics = null;
  121. //线程池
  122. private transient ToePool toePool;

同时属性中有三个地方需要补充下:

1)"CHECKPOINTING".intern(); 为什么采用intern()方法?知道intern()方法的人都知道,intern在创建String对象时会先无内存里查看有没有该对象,有的话直接返回,没有则重新创建。而普通的new一般都是直接创建对象,如此在一定程序上可以节省开销

2)transient LinkedList<char[]> reserveMemory;应急内存。Heritrix在初始化的时候会先占用一部分内存,这里是6M。当发生内存溢出的时候则释放这部分内存,然后做一些日志、报告方面的操作

3)private transient ReentrantLock singleThreadLock,重入锁.大脑只能有一个,所以需要用这个来保证一个大脑的存在,而不是多个。这里为什么不用单例模式来取代,而采用这种方法?我这里没有用单例模式和这种方法进行实验比较,但直觉上告诉我,由于Heritrix是个多线程爬虫,并且可以同时有多个抓取Job,但同时只能有一个job运行。单例模式的synchronized不能保证当一个job发生线程中断时,其他job可以获得CrawlController的锁来运行他们的抓取,因为synchronized会一直锁住CrawlController对象.而使用ReentrantLock则可以做到这一点...我的想法,欢迎大家拍砖...

由于贴上方法介绍后本文章会太长,故方法介绍方法下一篇博客介绍,博客地址:http://guoyunsky.iteye.com/blog/650744

Heritrix源码分析(十二) Heritrix的控制中心(大脑)CrawlController(一)(转)的更多相关文章

  1. Heritrix源码分析(十四) 如何让Heritrix不间断的抓取(转)

    欢迎加入Heritrix群(QQ):109148319,10447185 , Lucene/Solr群(QQ) :  118972724 本博客已迁移到本人独立博客: http://www.yun5u ...

  2. Heritrix源码分析(十四)

    近段时间在搞定Lucene的一些问题,所以Heritrix源码分析暂时告一段落.今天下午在群里有同学提到了Heritrix异常终止的问题以及让Heritrix不停的抓取(就是抓完一遍后载入种子继续抓取 ...

  3. ABP源码分析十二:本地化

    本文逐个分析ABP中涉及到locaization的接口和类,以及相互之间的关系.本地化主要涉及两个方面:一个是语言(Language)的管理,这部分相对简单.另一个是语言对应得本地化资源(Locali ...

  4. [Abp 源码分析]十二、多租户体系与权限验证

    0.简介 承接上篇文章我们会在这篇文章详细解说一下 Abp 是如何结合 IPermissionChecker 与 IFeatureChecker 来实现一个完整的多租户系统的权限校验的. 1.多租户的 ...

  5. jQuery 源码分析(十二) 数据操作模块 html特性 详解

    jQuery的属性操作模块总共有4个部分,本篇说一下第1个部分:HTML特性部分,html特性部分是对原生方法getAttribute()和setAttribute()的封装,用于修改DOM元素的特性 ...

  6. Vue.js 源码分析(十二) 基础篇 组件详解

    组件是可复用的Vue实例,一个组件本质上是一个拥有预定义选项的一个Vue实例,组件和组件之间通过一些属性进行联系. 组件有两种注册方式,分别是全局注册和局部注册,前者通过Vue.component() ...

  7. Heritrix源码分析(十五) 各种问题总结(转)

    开博客以及建立Heritrix 群有一段时间了(这里谢谢大家的关注),这篇博客将整理这段时间所遇到的问题.同时由于自己从今年5月份开始就不怎么接触Heritrix,很多东西开始遗忘(不过里面思想没忘) ...

  8. Heritrix源码分析(十五)

    开博客以及建立Heritrix 群有一段时间了(这里谢谢大家的关注),这篇博客将整理这段时间所遇到的问题.同时由于自己从今年5月份开始就不怎么接触Heritrix,很多东西开始遗忘(不过里面思想没忘) ...

  9. Heritrix源码分析(十) Heritrix中的Http Status Code(Http状态码)(转)

    本博客属原创文章,欢迎转载!转载请务必注明出处:http://guoyunsky.iteye.com/blog/649737       本博客已迁移到本人独立博客: http://www.yun5u ...

随机推荐

  1. 怎样强制QQ聊天

    首先复制下面这段网址: http://wp.qq.com/open_webaio.html?sigt=2d3bb7d31517da8c94a1061c6b63dd3203eb633805dcd09ec ...

  2. URAL 1152. False Mirrors (记忆化搜索 状压DP)

    题目链接 题意 : 每一颗子弹破坏了三个邻近的阳台.(第N个阳台是与第1个相邻)射击后后的生存的怪物都对主角造成伤害- 如此,直到所有的怪物被消灭,求怎样射击才能受到最少伤害. 思路 : 状压,数据不 ...

  3. hdu 1538 A Puzzle for Pirates 博弈论

    很经典的问题,思路转载自http://blog.csdn.net/ACM_cxlove?viewmode=contents 题目:这是一个经典问题,有n个海盗,分m块金子,其中他们会按一定的顺序提出自 ...

  4. (11)nehe教程5---3D空间

    3D空间: 我们使用多边形和四边形创建3D物体,在这一课里,我们把三角形变为立体的金子塔形状,把四边形变为立方体. 在上节课的内容上作些扩展,我们现在开始生成真正的3D对象,而不是象前两节课中那样3D ...

  5. java语言写文件内容

    import java.io.File;import java.io.FileWriter;import java.io.IOException; public static void main(St ...

  6. win10开机密码怎么取消

    win10怎么取消电脑开机密码?比较快捷的方法就是使用netplwiz在WIN2000以后的版本都是适用.最新版的WIN10同样也是适用的.下面我来演示一下win10开机密码怎么取消? 1. WIN1 ...

  7. 李洪强iOS开发之苹果使用预览截图

    李洪强iOS开发之苹果使用预览截图 01 在预览的图片中选中你要截得区域  02 - command + C   03 - Command + N 04 - Command + S (保存)

  8. linux 操作系统下c语言编程入门

    2)Linux程序设计入门--进程介绍 3)Linux程序设计入门--文件操作 4)Linux程序设计入门--时间概念 5)Linux程序设计入门--信号处理 6)Linux程序设计入门--消息管理  ...

  9. OSI

    1.物理(硬:HUB位) *****************信道接口型状.尺寸.引脚.排列电压.电流.阻抗.波形.速率及平衡单.半双.全双工RS232,RS422,RS423,RS485X.25.X. ...

  10. Oracle ->> 层级查询语句(hierarchical query)connect by

    Oracle中的Connect By... Start With语句实现了递归查询或者树状查询. Connect By Prior 一方为起始(root)的ID 参考: http://www.360d ...