多线程爬取 API 数据,怎么设计比较好?

2017-06-03 08:36:20 +08:00
 id4alex
自己有一个 web 站点,有从 api 获取数据。API 结构大概有这两种类型,一种是需要传递参数构造 URL, 一种是不需要参数。
http://api.example.com/api/resourceA/${pageIndex}
http://api.example.com/api/resourceLatest/

大约有 6 个需要获取数据的 API 接口。


每个 API 接口我都定义了一个 Runnable 与和一个 Threadpool 之对应.
Map<Class<? extends Runnable>, ExecutorService> threadsMap = new HashMap<>();

然后提交 Runnable 到 threadpool:
1 )带参数的 Runnable 需要从数据库任务表(有任务状态标注)获取参数来构造。
2 )不带参数的,直接提交排队即可。

之前我会在 Runnable 里面去判断 threadpool queue 的数量,然后再提交,但是自己觉得这种方式很糟糕,所以想请教下大家这种情况下,大家有什么好的设计可以让程序更优雅点?
2117 次点击
所在节点    问与答
9 条回复
D3EP
2017-06-03 11:51:21 +08:00
判断 queue 的数量是为了什么?没明白啥意思。
0915240
2017-06-03 12:19:58 +08:00
没明白 直接提交有啥问题
hand515
2017-06-03 13:59:17 +08:00
blockingQueue 阻塞队列不满足吗?
id4alex
2017-06-03 18:30:52 +08:00
@0915240
比如有 1W、10W、100W 条记录全部提交进去是不是不太好?
所以我选择分批提交, 当 queue 队列的 size 达到一个值的时候再添加任务。
那么问题来了, 怎么自动提交任务的实现比较优雅
id4alex
2017-06-03 18:31:19 +08:00
@D3EP
@hand515

参考楼上
0915240
2017-06-03 19:12:45 +08:00
@id4alex 让线程池去帮你管理啊 自己管理 queue 不如线程池管理 配置高线程池参数就行了。


不知道我有没有好好审题


还是说你怕一下子请求别人过多不好的感觉?如果是这种的话可以控制请求流速。用不着分批吧,细水长流可以的。


不知道现在有没有身体问题。
0915240
2017-06-03 19:13:48 +08:00
@0915240 彩色 v2 app 不能换行好不开森。
Buffer2Disk
2017-06-03 19:37:58 +08:00
不是很懂你说的啥意思,线程池默认就是可以帮你去管理线程的,你可以试试下面这个。
newFixedThreadPool
创建固定大小的线程池。每次提交一个任务就创建一个线程,直到线程达到线程池的最大大小。线程池的大小一旦达到最大值就会保持不变,如果某个线程因为执行异常而结束,那么线程池会补充一个新线程。
hand515
2017-06-03 20:03:01 +08:00
ArrayBlockingQueue 有界阻塞队列,满了就阻塞插入操作

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

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

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

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

© 2021 V2EX