爬虫: Goroutine 如何并行抓取网页

2016-10-05 00:05:07 +08:00
 TheCure

在写一道公司的题目,完成一个爬虫,题目要求之一是

要求支持多 routine 并行抓取(注意:这里并不是指简单设置 GOMAXPROCS>1)

然后我就懵了,怎么样才是并行抓取?我现在只知道设置 runtime.GOMAXPROCS=N

设置 GOMAXPROCS 是并行抓取吗,为什么?

不是很明白出题人的意思...

1369 次点击
所在节点    Go 编程语言
18 条回复
lujiajing1126
2016-10-05 00:32:16 +08:00
就是写个任务调度框架吧😂
miyuki
2016-10-05 00:32:52 +08:00
magicdawn
2016-10-05 00:49:11 +08:00
1. 这个 IO 密集型, 像 Node.js 这样单进程也可以完成的很好, Promise.map + concurrency
2. golang: https://github.com/magicdawn/go-co/tree/master 用 task.map
https://github.com/magicdawn/go-co/blob/master/task/map.go#L11
magicdawn
2016-10-05 00:55:08 +08:00
你的意思是: 可以提交很多个 routine, 然后设置 runtime.GOMAXPROCS=cpu 核心数, 但是这样是不行的, 会导致所有的 routine 都进行了 request
题目意思可能是: 只有那么几个 concurrency routine 在跑, 一个结束了, 开始处理新的
magicdawn
2016-10-05 00:55:51 +08:00
前面那一种是相当于 concurrency = Infinity
miyuki
2016-10-05 01:16:46 +08:00
http://jmoiron.net/blog/limiting-concurrency-in-go/

楼上提到 limit concurrency 的一种方法
janxin
2016-10-05 10:39:13 +08:00
应该是想说 worker pool 吧?

https://gobyexample.com/worker-pools
TheCure
2016-10-05 13:35:06 +08:00
@magicdawn
我是这么想的 我只开 8 个 routine,不停的从 channel/queue 里面读抓取的网址然后去爬它.

但是如果我不开 GOMAXPROCS,那么每一个瞬间,都最多只有一个 routine 在跑,这只是利用异步 IO 在并发.

但是只要我设置了 GOMAXPROCS,这些 routine 就会被调度到不同的线程->不同的 CPU,这样才是并行

所以这里并行的关键是设置 GOMAXPROCS 对吧,那题目说的不是简单设置 GOMAXPROCS,这才是让我困惑的地方,我以为有什么其他的方法来实现并行
reus
2016-10-05 15:59:05 +08:00
开 N 个 gorutine ,读 chan 里的任务,就这么简单,什么第三方库都不用。
这么基础的东西还要来 V2EX 问?贵司心略宽啊。
reus
2016-10-05 15:59:49 +08:00
@callofmx 不用管 GOMAXPROCS 的事,默认是 cpu 核数,会用上所有核心的了
magicdawn
2016-10-05 17:45:01 +08:00
对于有限长度的队列, 如 []int{ 1, 2, 3, 4 }
job 为 sleep i 秒, 使用并发为 2 的时候, 耗时为 6s(2 + 4)
https://github.com/magicdawn/go-co/blob/master/demo/map/main.go

长度变化的队列, 工作中碰到的都是
while true
拿出 1000 个
等待 1000 个以某个并发完成
continue
再不行, 将 async.parallelLimit 代码抄下来写一点

啊, 这种还是 nodejs 来的简单...
TheCure
2016-10-05 22:22:04 +08:00
@reus
关于 GOMAXPROCS,版本不到 1.5

我厂有国内流量最大的 Go 项目
reus
2016-10-06 00:04:45 +08:00
@callofmx 百度吧?

我的意思是,为什么你这都不会写还……
buckethead1
2016-10-06 00:24:12 +08:00
@reus lz 的意思是,并行的关键就是简单设置 GOMAXPROCS ,你怎么看出来不会写
reus
2016-10-06 01:14:55 +08:00
@buckethead1
“爬虫: Goroutine 如何并行抓取网页”
“然后我就懵了,怎么样才是并行抓取?我现在只知道设置 runtime.GOMAXPROCS=N ”
我现在只知道设置
我现在只知道设置
我现在只知道设置

我是这样看出来不会写的。
reus
2016-10-06 01:19:30 +08:00
@buckethead1 就爬虫这个例子,不论 GOMAXPROCS 是 1 还是几,都能写出并行抓取的爬虫,因为主要工作都是 net poller 做的, goroutine 并不需要多少 cpu 时间片。
主要工作是网络 io 的场景, GOMAXPROCS 和并行没有关系。
p2p
2016-10-06 07:31:39 +08:00
楼主还不知道并发并行的区别
wweir
2016-10-06 09:49:09 +08:00
一年多前自己的实现是 buffer chan

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/310595

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX