爬虫(三)-NIO下载服务NIOFetcher的设计
来源:互联网 发布:探险电影知乎 编辑:程序博客网 时间:2024/06/07 04:48
之前写的一个爬虫下载部分使用HttpClient,效率相当不敢恭维,最近打算使用NIO实现该部分,记录一下设计及实现过程中遇到的的问题。
一.基本思路
以下为可能会犯的错误
1.连接到同一服务器的SocketChannel数量过多
看到很多人用SocketChannel模拟Http请求实现方式几乎都是为每一个域名下的URL注册一个SocketChannel,这种方式有一个弊端,不论从横向(多域名)还是纵向(同一域名),SocketChannel的总量不好控制,这就使我们很难在带宽与下载效率上进行权衡。
2.频繁的打开、关闭SocketChannel
我们很期望从本机到远程服务器能够建立几个相对稳定的长连接,以减少频繁打开、关闭Socket连接的资源消耗,但是还有另外一个问题:我们需要礼貌爬取,即使你选择"疯狂"爬取,也要考虑远程服务器强制关闭Socket连接的问题。权衡一下,我更倾向于使Socket可以保持一定时间的连接(可以叫做半长连接),打开一定时间的Socket连接在完成最后一次下载任务后就要关闭。
综合以上两个因素,我选择为同一域名的URL注册一定数量的(可配置,以适应下载服务器的性能与带宽的变动)Socket连接,以该值为阀值并辅以Socket连接服务时长对Socket连接数量进行横向与纵向的控制。
二.设计
主要结构如下图所示:
其中IURLRegister与IFetchedURLHandler分别供爬行模块与文件持久化模块调用。
三.主要接口及实现类代码
package com.crazygeeker.search.fetcher;/** * A service designed for download remote file. * <p>Provide basic operations such as <tt>start</tt><tt>shutdown</tt></p> * @author JohnWang * @version 1.0 * @date 2013-11-11 */public interface IFetcher {void start();void shutdown();}
package com.crazygeeker.search.fetcher;import com.crazygeeker.search.common.model.URLBean;/** * register the url waiting for downloading * * @author JohnWang * @version 1.0 * @date 2013-11-11 */public interface IURLBeanRegister {/** * * @param urlBean * @return */boolean register(URLBean urlBean);}
package com.crazygeeker.search.fetcher;import com.crazygeeker.search.common.model.URLBean;/** * An interface for data upload * @author JohnWang * @version 1.0 * @date 2013-11-11 */public interface IFetchedURLHandler {URLBean getURLBean();}
package com.crazygeeker.search.fetcher;import java.io.IOException;import java.nio.channels.Selector;import java.util.concurrent.BlockingQueue;import java.util.concurrent.LinkedBlockingQueue;import java.util.concurrent.PriorityBlockingQueue;import java.util.concurrent.atomic.AtomicBoolean;import com.crazygeeker.search.common.model.URLBean;import com.crazygeeker.search.common.utils.LoggerUtils;/** * * @author JohnWang * @version 1.0 * @date 2013-11-11 */public abstract class AbstractNIOFetcher implements IFetcher {protected Selector selector;/** * */protected AtomicBoolean isRunning = new AtomicBoolean(false);/** * */protected BlockingQueue<URLBean> pendingQueue = new PriorityBlockingQueue<URLBean>(); /** * */protected BlockingQueue<URLBean> fetchedQueue = new LinkedBlockingQueue<URLBean>();/** * */public void start() {try {selector = Selector.open();} catch (IOException e) {e.printStackTrace();LoggerUtils.fetcherLogger.error("error.cannot_open_selector",e);}isRunning.set(true);LoggerUtils.fetcherLogger.info("selector has bean opened");service();}protected abstract void service();/** * */public void shutdown(){try {selector.close();} catch (IOException e) {e.printStackTrace();LoggerUtils.fetcherLogger.error("error.cannot_close_selector",e);}LoggerUtils.fetcherLogger.info("selector has bean closed");}}
- 爬虫(三)-NIO下载服务NIOFetcher的设计
- nio的下载
- urllib2下载网页的三种方法_Python爬虫
- 用java nio模拟下载服务
- NIO通讯库的设计
- 爬虫的下载、解析、存储
- java nio学习:简单的echo服务
- Java NIO 的前生今世 之三 NIO Buffer 详解
- NIO学习三、基于NIO的WEB服务器
- 一个基于NIO的下载队列实现
- java IO/NIO 下载上传的笔记
- 农业垂直搜索引擎三》爬虫机器人模块的设计与实现
- 网络爬虫的设计分析
- python 网络爬虫(三) 多线程,gzip加速,网页下载
- 1号小爬虫:普通的爬虫,下载百度壁纸
- 【Python爬虫3】在下载的本地缓存做爬虫
- Java NIO 设计底层的一些东西
- 一个下载pdf的简单python爬虫
- 【Android每周专题】Android中的逆向工程
- hibernate的一些问题
- PHP 实现定时任务的几种方法
- 9秒 双十一 给力活动!!!【9秒社区 Firely 开源框架 】官方教程 资源下载!!
- 更改故障转移群集实例的 IP 地址
- 爬虫(三)-NIO下载服务NIOFetcher的设计
- 2013年下半年系统架构师备考材料整理
- 13个mysql数据库的实用SQL小技巧
- 【MySQL】批量检查表并进行repair,optimize
- VC程序实现开机自启动
- C语言中使用静态函数的好处
- css兼容多浏览器强制换行与不换行
- 西安保障房优先配建公交场站
- 寄存器单位的设置问题