资讯专栏INFORMATION COLUMN

spiderman2 源码解读

harriszh / 2686人阅读

摘要:先上一张架构图的事件传递的主要通过通道也就是图中的这三个是阻塞队列。

先上一张架构图

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;
}

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/69200.html

相关文章

  • React 源码深度解读(三):首次 DOM 元素渲染 - Part 3

    摘要:在学习源码的过程中,给我帮助最大的就是这个系列文章,于是决定基于这个系列文章谈一下自己的理解。到此为止,首次渲染就完成啦总结从启动到元素渲染到页面,并不像看起来这么简单,中间经历了复杂的层级调用。 前言 React 是一个十分庞大的库,由于要同时考虑 ReactDom 和 ReactNative ,还有服务器渲染等,导致其代码抽象化程度很高,嵌套层级非常深,阅读其源码是一个非常艰辛的过...

    U2FsdGVkX1x 评论0 收藏0
  • React 源码深度解读(六):依赖注入

    摘要:依赖注入和控制反转,这两个词经常一起出现。一句话表述他们之间的关系依赖注入是控制反转的一种实现方式。而两者有大量的代码都是可以共享的,这就是依赖注入的使用场景了。下一步就是创建具体的依赖内容,然后注入到需要的地方这里的等于这个对象。 前言 React 是一个十分庞大的库,由于要同时考虑 ReactDom 和 ReactNative ,还有服务器渲染等,导致其代码抽象化程度很高,嵌套层级...

    glumes 评论0 收藏0
  • 来一打前端博客压压惊

    前言 本文所有内容全部发布再个人博客主页 https://github.com/muwoo/blogs欢迎订阅。不过最近因为事情比较多,有一段时间没有更新了,后面打算继续不断学习更新,欢迎小伙伴一起沟通交流~ 最近更新 前端单测的那些事 基于virtual dom 的canvas渲染 js Event loop 机制简介 axios 核心源码实现原理 JS 数据类型、赋值、深拷贝和浅拷贝 j...

    wangbinke 评论0 收藏0
  • 来一打前端博客压压惊

    前言 本文所有内容全部发布再个人博客主页 https://github.com/muwoo/blogs欢迎订阅。不过最近因为事情比较多,有一段时间没有更新了,后面打算继续不断学习更新,欢迎小伙伴一起沟通交流~ 最近更新 前端单测的那些事 基于virtual dom 的canvas渲染 js Event loop 机制简介 axios 核心源码实现原理 JS 数据类型、赋值、深拷贝和浅拷贝 j...

    villainhr 评论0 收藏0
  • 来一打前端博客压压惊

    前言 本文所有内容全部发布再个人博客主页 https://github.com/muwoo/blogs欢迎订阅。不过最近因为事情比较多,有一段时间没有更新了,后面打算继续不断学习更新,欢迎小伙伴一起沟通交流~ 最近更新 前端单测的那些事 基于virtual dom 的canvas渲染 js Event loop 机制简介 axios 核心源码实现原理 JS 数据类型、赋值、深拷贝和浅拷贝 j...

    xiaoqibTn 评论0 收藏0

发表评论

0条评论

harriszh

|高级讲师

TA的文章

阅读更多
最新活动
阅读需要支付1元查看
<