V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
liian2019
V2EX  ›  Java

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

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

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

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

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

    你现在最好的情况是 做横向扩展,在双 12 当天加机器,同时做一下网关层的限流
    liian2019
        4
    liian2019  
    OP
       2021-12-06 17:12:54 +08:00
    @Joker123456789 对顺序倒是没有要求,但是保证线程池里不会挤压任何任务,这个现实实现起来太难了,所以说线程池在这种场景下还是很难使用的。
    liian2019
        5
    liian2019  
    OP
       2021-12-06 17:18:39 +08:00
    @realrojeralone 暂时先不搞了 风险太大了 不如堆机器来的实在,瓶颈抛给下游业务
    tanweiiiii
        6
    tanweiiiii  
       2022-01-02 16:05:51 +08:00
    用线程池接收请求后发送到 MQ 队列慢慢消费, 根据流量水平扩展 MQ 和消费端
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   2776 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 23ms · UTC 15:11 · PVG 23:11 · LAX 07:11 · JFK 10:11
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.