spiderman2 源码解读

先上一张架构图
图片描述

spiderman2的事件传递的主要通过queue通道也就是图中的DQ,EQ,RQ;这三个是阻塞队列。Worker来消费队列,Manager来处理任务流向哪个队列

public static void main(String[] args) {
    final String xml = "xiaomibbs.xml";
    final Config conf = new XMLConfBuilder(xml).build();// 解析xml配置文件通过XMLBuilder构建CONF对象
    new Spiderman(conf).go();//启动,别忘记看控制台信息哦,结束之后会有统计信息的
}

创建一个Spiderman

public Spiderman(Config config) {//将配置文件初始化到上下文
    this.context = new Context(config); 
    final Properties params = context.getParams(); 
    this.scheduler = Executors.newSingleThreadScheduledExecutor();
    this.managers = context.getManagers();
    this.managers.forEach(m -> {
        m.addListener(() -> { 
            counter.plus(); 
        });
    });
    this.threads = Executors.newFixedThreadPool(managers.size());
    duration = K.convertToMillis(params.getString("duration", "0")).longValue();
    counter = new Counter(managers.size(), duration);
}

开始执行抓取

public Spiderman go() {
    logger.debug("开始行动...");
    // 启动各个工头,启动所有的downloadWorker,extractWorker,resultWorker,开始等待阻塞队列的数据
    this.managers.forEach(m -> threads.execute(m));
    // 调度, 固定一段时间清除种子和一些中间过程任务,重新将种子放入任务队列
    final InitialSeeds initSeeds = new InitialSeeds();
    final String cron = context.getParams().getString("scheduler.cron");
    if (K.isNotBlank(cron)) {
        // quartz
        
    } else {
        final long period = K.convertToMillis(context.getParams().getString("scheduler.period", "0")).longValue();
        if (period > 0) {
            this.scheduler.scheduleAtFixedRate(initSeeds, 5000, period, TimeUnit.MILLISECONDS);
        } else {
            //开始处理种子请求,将种子请求初始化成DownloadTask对象并塞到DQ
            initSeeds.execute();
        }
    }

    Thread thread = new Thread(() -> {
        // 阻塞等待计数器归0
        try {
            this.counter.await();
        } finally {
            if (this.counter.isTimeout()) {
                // 若是超时退出,先关闭manager
                logger.warn("运行时间["+this.counter.getCost()+"]已经达到或超过设置的最大运行时间[duration="+this.duration+"],将强行停止行动");
                this.stop();
            } else {
                logger.warn("当前采集的结果数["+this.counter.get()+"]已经达到或超过设置的最大数量[worker.result.limit="+this.counter.getLimit()+"],将强行停止行动");
            }
            this._stop();
        }
    });
    thread.start();
    
    return this;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值