关于线程池在高并发场景下落地使用的疑惑?

2021-12-03 10:25:55 +08:00
 liian2019
好比我现在有这么一个场景,我一个列表查询接口,在双 12 活动的时候并发会很高。而这个列表接口需要依赖 N 个外部接口查询的结果,如果这些外部接口查询都是串行的话整个方法响应时间相对较高,想用线程池去并发调用这些外部接口,这样瓶颈就会落在最耗时的一次外部接口调用上了。但是这个设想很快就被自己否定了,因为线程池的核心线程数也不是无限的,一次请求带来的是多个线程池线程被使用,在高并发场景下很快核心线程数就会别打满,更多的请求会进入等待队列,这样感觉会得不偿失。
想请教下大家,有没有碰到过类似的问题,这种问题是否只能靠水平扩展来解决,通过负载均衡使更多的机器来处理用户请求。大家有没有在对 C 的场景使用过线程池呢?
1256 次点击
所在节点    Java
6 条回复
mazyi
2021-12-03 10:39:27 +08:00
对,你是对的,需要加机器
realrojeralone
2021-12-03 11:59:04 +08:00
外部接口调用是 IO 密集型,并不会耗费很多 CPU ,尝试把线程池调大,使用 callback 而不是直接 get 结果,另外资源限制也是一方面,评估单机承受的压力,必要时扩容,最后,第三方接口也可能扛不住,需要做压力评估
Joker123456789
2021-12-06 12:17:32 +08:00
需要等结果的场景,不适合用异步。 异步只适用于不需要等结果的场景,主要是为了快速响应的。

而且你这种情况,对顺序也有严格的要求吧,你可能需要等 A 接口返回了,用 A 接口的返回结果去执行下一步 调 B 接口,用 B 的返回结果调 C 接口对吧? 如果是这样的话,那多线程的意义就更是彻底被玩没了, 反正都要等了为什么还要用线程?

如果不需要等,对顺序没有任何要求,只要调了就行,那或许还可以试试。但前提是 平常的压力之下,这些三方接口的处理速度必须要 > 生产速度,务必保证线程池里不会挤压任何任务。 让线程池 只用于应对 突发流量,保护三方接口不会被压垮(传说中的削峰)。

线程池其实就是一个内存级别的消息队列

你现在最好的情况是 做横向扩展,在双 12 当天加机器,同时做一下网关层的限流
liian2019
2021-12-06 17:12:54 +08:00
@Joker123456789 对顺序倒是没有要求,但是保证线程池里不会挤压任何任务,这个现实实现起来太难了,所以说线程池在这种场景下还是很难使用的。
liian2019
2021-12-06 17:18:39 +08:00
@realrojeralone 暂时先不搞了 风险太大了 不如堆机器来的实在,瓶颈抛给下游业务
tanweiiiii
2022-01-02 16:05:51 +08:00
用线程池接收请求后发送到 MQ 队列慢慢消费, 根据流量水平扩展 MQ 和消费端

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

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

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

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

© 2021 V2EX