golang实现并发爬虫二(简单调度器)
那么这篇文章就大概说下,如何在上一个版本中进行升级改造,使之成为一个多任务版本的爬虫。加快我们爬取的速度。
话不多说,先看图:

其实呢,实现方法就是加了一个scheduler的模块,所有的request都由scheduler去交给worker。
另外呢,这里的worker,也就是上文提到过的fetcher和parser的一个过程。
worker的数量由我们自己在调用engine的时候传入。
每一个worker都是一个groutine。这样可以加快抓取速度,尤其是fetcher那块的。代码如下:
func createWorker(in chan Request, out chan ParseResult) {
go func() {
for {
request := <-in
res, err := Worker(request)
if err != nil {
continue
}
out <- res
}
}()
}
这里的关键呢,就在于scheduler如何分配。
第一种方案是来一个request就给到workChan。
func (s *SimpleScheduler) Submit(r simple_con_engine.Request) {
s.workChan <- r
}
但是,这种方案是不行的。
因为worker的速度太快,而这个给到workChan的速度太慢,会导致卡死。
那么,解决办法可以是每来一个request就都开一个groutine,就可以解决这个事情了。代码也就是这样了:
func (s *SimpleScheduler) Submit(r simple_con_engine.Request) {
go func() { s.workChan <- r }()
}
scheduler做的事情也就是这样了:

这个就可以并发的去执行爬虫的任务了,通过这个scheduler的调度。
经测当workerCount为1时,其实也就相当于是单任务版爬虫为30秒爬取了2046条数据。
当workerCount为10时,这个使用了简单调度器的爬虫为30秒爬取了条数据,实际效率不止增加了10倍。


这个使用scheduler去实现简单调度器的并发版爬虫的源码可有:
有。
https://github.com/anmutu/du_crawler/tree/master/03crawler
那么,这个多任务版本的爬虫有什么缺点吗:
有。
当engine给到scheduler的每一个request的时候就会创建一个groutine,这个避免dead lock,但是就会创建无数个groutine,我们的控制力度就小了好多。
golang实现并发爬虫二(简单调度器)的更多相关文章
- golang实现并发爬虫三(用队列调度器实现)
欲看此文,必先可先看: golang实现并发爬虫一(单任务版本爬虫功能) gollang实现并发爬虫二(简单调度器) 上文中的用简单的调度器实现了并发爬虫. 并且,也提到了这种并发爬虫的实现可以提高爬 ...
- golang中GPM模型原理与调度器设计策略
一.GMP模型原理first: 1. 全局队列:存放待运行的G2. P的本地队列:同全局队列类似,存放待运行的G,存储的数量有限:256个,当创建新的G'时,G'优先加入到P的本地队列,如果队列已满, ...
- golang实现并发爬虫一(单任务版本爬虫功能)
目的是写一个golang并发爬虫版本的演化过程. 那么在演化之前,当然是先跑通一下单任务版本的架构. 正如人走路之前是一定要学会爬走一般. 首先看一下单任务版本的爬虫架构,如下: 这是单任务版本爬虫的 ...
- golang版并发爬虫
准备爬取内涵段子的几则笑话,先查看网址:http://www.budejie.com/text/ 简单分析后发现每页的url呈加1趋势 第一页: http://www.budejie.com/text ...
- python简单爬虫(二)
上一篇简单的实现了获取url返回的内容,在这一篇就要第返回的内容进行提取,并将结果保存到html中. 一 . 需求: 抓取主页面:百度百科Python词条 https://baike.baidu. ...
- golang的并发
Golang的并发涉及二个概念: goroutine channel goroutine由关键字go创建. channel由关键字chan定义 channel的理解稍难点, 最简单地, 你把它当成Un ...
- scrapy 基础组件专题(七):scrapy 调度器、调度器中间件、自定义调度器
一.调度器 配置 SCHEDULER = 'scrapy.core.scheduler.Scheduler' #表示scrapy包下core文件夹scheduler文件Scheduler类# 可以通过 ...
- 第十四章 kubernetes 核心技术-调度器
一.概述 一个容器平台的主要功能就是为容器分配运行时所需要的计算,存储和网络资源.容器调 度系统负责选择在最合适的主机上启动容器,并且将它们关联起来.它必须能够自动的处 理容器故障并且能够在更多的主机 ...
- YARN的capacity调度器主要配置分析
yarn中一个基本的调度单元是队列. yarn的内置调度器: 1.FIFO先进先出,一个的简单调度器,适合低负载集群.2.Capacity调度器,给不同队列(即用户或用户组)分配一个预期最小容量,在每 ...
随机推荐
- 通用mapper常用注解
通用mapper的作用: 自动实现单表的增删改查 常用注解使用 @Table 作用:建立实体类和数据库表之间的对应关系. 默认规则:实体类类名首字母小写作为表名.Employee 类→employee ...
- dp例题02. 滑雪问题 (poj1088)
poj1088滑雪问题 题目链接:http://poj.org/status Michael喜欢滑雪百这并不奇怪, 因为滑雪的确很刺激.可是为了获得速度,滑的区域必须向下倾斜,而且当你滑到坡底,你不得 ...
- Window.requestAnimationFrame()动画更新
概述 Window.requestAnimationFrame()方法告诉浏览器你希望执行动画,并且再下一次重绘之前要求浏览器调用一个特定的函数去更新动画.该方法把一个回调函数作为参数,该回调函数会在 ...
- echarts整理
保存一些常用的echarts图表及制作方法
- PTA数据结构与算法题目集(中文) 7-23
PTA数据结构与算法题目集(中文) 7-23 7-23 还原二叉树 (25 分) 给定一棵二叉树的先序遍历序列和中序遍历序列,要求计算该二叉树的高度. 输入格式: 输入首先给出正整数N(≤50) ...
- AbstractQueuedSynchronizer概述
AbstractQueuedSynchronizer 是一个用于在竞争资源(如多线程)时使用的同步器,它内部使用了一个int类型的字段status表示需要同步的资源状态, 并基于一个先进先出(FIFO ...
- ssh 解决经常断开与记住密码功能
一.解决ssh经常自动断开问题 修改 /etc/ssh/sshd_config 其中对应项为 ClientAliveInterval 30 ClientAliveCountMax 3 表示每30秒发一 ...
- 052.Kubernetes集群管理-故障排错指南
一 故障指南 1.1 常见问题排障 为了跟踪和发现在Kubernetes集群中运行的容器应用出现的问题,常用如下查错方法: 查看Kubernetes对象的当前运行时信息,特别是与对象关联的Event事 ...
- python--一些知识点
一. ==和is的区别 1. ==意为左右两端的值是否相等 2. is意为,左边是否就是右边,python会检测左右两边的引用位置,相等才是True(注:一定范围内的数字,左右两边为True) 二. ...
- BadMethodCallException : Call to undefined method App\Models\Article::setContainer()
如果你执行 php artisan db:seed 发生如下错误 说是模型中不存在 静态方法 setContainer()方法,那么你应该检查下你的DatabaseSeeder.php 文件 中的 r ...