Heritrix源碼分析(十二) Heritrix的控制中心(大腦)CrawlController(一)文章分類:互聯(lián)網(wǎng)本博客屬原創(chuàng)文章,歡迎轉(zhuǎn)載!轉(zhuǎn)載請務必注明出處:http://guoyunsky./blog/650694 歡迎加入Heritrix群(QQ):10447185
CrawlController的確是Heritrix的大腦,在Heritrix中擁有無上的權(quán)利!可以控制Heritrix的啟動、暫停、停止,也定時進行數(shù)據(jù)統(tǒng)計、數(shù)據(jù)匯報和文件管理。同時CrawlController也基本上貫穿整個Heritrix代碼,和CrawlURI一樣。同時CrawlController純代碼頁進2000行,下面就先介紹里面的屬性和主要方法,同時對一些靈活用法也加以介紹: 1.屬性:
//狀態(tài),Checkpoinging:表示正在備份 private static final Object CHECKPOINTING = "CHECKPOINTING".intern(); //狀態(tài),FINISHED:表示抓取結(jié)束 private static final Object FINISHED = "FINISHED".intern(); //狀態(tài),NASCENT:表示正在生成一個JOB private static final Object NASCENT = "NASCENT".intern(); //狀態(tài),PAUSED:表示暫停結(jié)束,該狀態(tài)Heritrix正暫停任何抓取 private static final Object PAUSED = "PAUSED".intern(); //狀態(tài),PAUSING:表示正在暫停,傳達一個暫停命令到每一個線程暫停中間需要時間 private static final Object PAUSING = "PAUSING".intern(); //狀態(tài),PREPARING:表示抓取結(jié)束 private static final Object PREPARING = "PREPARING".intern(); //狀態(tài),RUNNING:表示正在運行 private static final Object RUNNING = "RUNNING".intern(); //狀態(tài),STARTED:表示已經(jīng)啟動 private static final Object STARTED = "STARTED".intern(); //狀態(tài),STOPPING:表示正在停止,傳達一個停止命令到每一個線程暫停中間需要時間 private static final Object STOPPING = "STOPPING".intern(); //當前類的日志管理器 private final static Logger LOGGER = Logger.getLogger(CrawlController.class .getName()); // 活動的日志文件名后綴 public static final String CURRENT_LOG_SUFFIX = ".log"; // 日志crawl.log.txt的文件名 private static final String LOGNAME_CRAWL = "crawl"; // 日志local-errors.log.txt的文件名 private static final String LOGNAME_LOCAL_ERRORS = "local-errors"; // 日志progress-statistics.log.txt的文件名 private static final String LOGNAME_PROGRESS_STATISTICS = "progress-statistics"; // runtime-errors.txt的文件名 private static final String LOGNAME_RUNTIME_ERRORS = "runtime-errors"; // 日志uri-errors.txt的文件名 private static final String LOGNAME_URI_ERRORS = "uri-errors"; // 日志manifest-report的文件名前綴 public final static String MANIFEST_REPORT = "manifest"; //processors-report.txt的文件名前綴 public final static String PROCESSORS_REPORT = "processors"; // crawl-manifest日志文件中中配置文件標簽縮寫 public static final char MANIFEST_CONFIG_FILE = 'C'; // crawl-manifest日志文件中中日志文件標簽縮寫 public static final char MANIFEST_LOG_FILE = 'L'; // crawl-manifest日志文件中中報告文件標簽縮寫 public static final char MANIFEST_REPORT_FILE = 'R'; //報告文件名數(shù)組 protected final static String[] REPORTS = { PROCESSORS_REPORT, MANIFEST_REPORT }; //應急內(nèi)存,當內(nèi)存不夠時Heritrix會釋放這個內(nèi)存去做一些緊急動作如數(shù)據(jù)備份 private static final int RESERVE_BLOCK_SIZE = 6 * 2 ^ 20; // 6MB private static final int RESERVE_BLOCKS = 1; //BDB數(shù)據(jù)庫,Heritrix自己封裝 private transient EnhancedEnvironment bdbEnvironment = null; //用于Checkpoint備份,存儲需要備份的數(shù)據(jù) private transient Map<String, CachedBdbMap<?, ?>> bigmaps = null; //備份器 private Checkpointer checkpointer; //備份對象 private transient Checkpoint checkpointRecover = null; //備份目錄 private transient File checkpointsDisk; //整個Heritrix目錄 private transient File disk; //日志文件目錄 private transient File logsDisk; //scratch文件 private transient File scratchDisk; //BDB數(shù)據(jù)庫文件 private transient File stateDisk; //日志處理器跟文件處理器關(guān)聯(lián) transient private Map<Logger, FileHandler> fileHandlers; //調(diào)度器 private transient Frontier frontier; // 日志處理器,關(guān)聯(lián)local-errors.log public transient Logger localErrors; // 日志處理器,關(guān)聯(lián) progress-statistics.log private transient Logger progressStats; //日志處理器,關(guān)聯(lián)報告文件 public transient Logger reports; // 日志處理器,關(guān)聯(lián)runtime-errors.log public transient Logger runtimeErrors; // 日志處理器,關(guān)聯(lián)uri-Errors.log public transient Logger uriErrors; // 日志處理器,關(guān)聯(lián)crawl.log public transient Logger uriProcessing; //記錄Hertrix創(chuàng)建的日志文件名 private StringBuffer manifest; //最大字節(jié)數(shù),來源于配置文件 private long maxBytes; // //抓取限制, 最大文檔數(shù),來源于配置文件 private long maxDocument; // 抓取限制,最大時間,來源于配置文件 private long maxTime; //管理order.xml private transient CrawlOrder order; //處理器鏈 private transient ProcessorChainList processorChains; //事件監(jiān)聽器,比如正在運行、停止 private transient List<CrawlStatusListener> registeredCrawlStatusListeners = Collections .synchronizedList(new ArrayList<CrawlStatusListener>()); //抓取狀態(tài)監(jiān)聽器,這里監(jiān)聽哪些URl被忽略,哪些URL抓取失敗等 private transient CrawlURIDispositionListener registeredCrawlURIDispositionListener; //抓取狀態(tài)監(jiān)聽器數(shù)據(jù) protected transient ArrayList<CrawlURIDispositionListener> registeredCrawlURIDispositionListeners; // 應急儲備內(nèi)存 private transient LinkedList<char[]> reserveMemory; //抓取范圍管理 private transient CrawlScope scope; // CrawlServer和CrawlHost的緩存 private transient ServerCache serverCache; //配置文件,如order.xml private transient SettingsHandler settingsHandler; //Heritrix狀態(tài),表示已經(jīng)存在 private transient String sExit; // 鎖,控制同時只能一個線程運行使用本類 private transient ReentrantLock singleThreadLock = null; //是否是單線程模式 private volatile transient boolean singleThreadMode = false; // 表示當前爬蟲狀態(tài),新生的 transient private Object state = NASCENT; // 統(tǒng)計跟蹤器 protected StatisticsTracking statistics = null; //線程池 private transient ToePool toePool;
同時屬性中有三個地方需要補充下: 1)"CHECKPOINTING".intern(); 為什么采用intern()方法?知道intern()方法的人都知道,intern在創(chuàng)建String對象時會先無內(nèi)存里查看有沒有該對象,有的話直接返回,沒有則重新創(chuàng)建。而普通的new一般都是直接創(chuàng)建對象,如此在一定程序上可以節(jié)省開銷 2)transient LinkedList<char[]> reserveMemory;應急內(nèi)存。Heritrix在初始化的時候會先占用一部分內(nèi)存,這里是6M。當發(fā)生內(nèi)存溢出的時候則釋放這部分內(nèi)存,然后做一些日志、報告方面的操作 3)private transient ReentrantLock singleThreadLock,重入鎖.大腦只能有一個,所以需要用這個來保證一個大腦的存在,而不是多個。這里為什么不用單例模式來取代,而采用這種方法?我這里沒有用單例模式和這種方法進行實驗比較,但直覺上告訴我,由于Heritrix是個多線程爬蟲,并且可以同時有多個抓取Job,但同時只能有一個job運行。單例模式的synchronized不能保證當一個job發(fā)生線程中斷時,其他job可以獲得CrawlController的鎖來運行他們的抓取,因為synchronized會一直鎖住CrawlController對象.而使用ReentrantLock則可以做到這一點...我的想法,歡迎大家拍磚...
由于貼上方法介紹后本文章會太長,故方法介紹方法下一篇博客介紹,博客地址:http://guoyunsky./blog/650744 |
|
來自: tianweibin > 《heritrix》