之前前面提到 爬虫 ,只是单纯的单条执行,既然用go来写爬虫,那么必须要用到 并发来做这件事情
废话不多说,先上 设计图
1 首先整个结构分为三层
第一层 定时更新器 层 timerupdate
第二层 调度层 dispatch
第三层 协程池层 pools
关系为
一个定时更新器—> 对应一个 调度器 也就是调度器管理一个定时更新器
比分说 有10个定时器 就对应有10 个调度器 ,比如控制一个调度器,开启一个定时器,或者stop 一个定时器
然后 调度层 管理多个调度器
调度层的功能主要是负责 创建一个调度器,通知一个调度器,去管理它自己的对应的 定时更新器
多个调度器里面的 任务 汇聚一起 发送给 任务池中 pools
//-------------------------下面是整个程序的执行顺序----------------------------
首先 当我们有任务来了,比方说抓取爬虫任务,我要抓取几个书籍分类的,但是众所周知 一个网站中一个分类下面有成千上万本书籍
但是我要同时抓取 这个网站上面所有 分类下面的,所有书籍
此时 我们可以把一个分类看成一个 定时抓取器,那么我们多个分类是不是就应该产生多个更新器呢,新的问题来了,我们该如何知道一个分类是不是抓取完了,还有就是我并不想抓取完整个分类的内容,
那么由此就有了调度器 来管理这些 定时更新器,A这个调度器,停止了A更新器,并不会影响我,其他的更新器 的抓取工作,
到了这里只是说明了,这个抓取任务的流程和控制**,最后的具体执行操作就该有 协程池来做具体的事情**,由调度层,下面的调度器,接收到了,定时器的任务,然后发送给,任务池也就是协程池,那么在协程池里面 就提供了通道 来接收调度器传递过来的任务也就是 图中的EC通道,有EC通道中,最后发送给任务池,此时的任务池里面就有之前调度层,给它,安排的多少个工作goroutine 来处理任务 。当 任务池中,有任务完成了,就由 任务池pools 提供ETC,对外发送通道–>来传递给,调度层,再由调度层,发出指令给调用器,在由调度器,控制定时更新器,
整个执行流程,就差不多是这样的。
(本来最开始,设计为 有调度器 产生多个任务池,但考虑到,可以利用增加,任务池的 worker goroutine的数量,同时为了简化整个程序的设计,就采用单一的任务池)
在本程序当中并没有使用 缓存通道和 sync 和同步锁等知识
有兴趣的朋友可以在后面加入这些知识在里面