layxy
0.66D
V2EX  ›  Java

Java 执行大量长耗时接口,怎么使用单机处理

  •  
  •   layxy · Jun 9, 2023 · 4847 views
    This topic created in 1244 days ago, the information mentioned may be changed or developed.

    目前使用的线程池,但是因为任务量太大,单机线程池和队列很快就满了,因为某些原因只能使用一台机器,有什么办法可以优化下

    Supplement 1  ·  Jun 12, 2023
    补充下,任务大部分都是查库,查 es,尤其是 es 比较慢
    Supplement 2  ·  Jun 12, 2023
    场景是这样的,我们有个定时任务,每隔一段时间触发,触发时会统计数据,查询 es 和 mysql,数据库倒还好,es 查询的比较多且慢,因为需要支持分布式任务调度,无论我扩容多少台,都只会调度到一台机器上,想过使用 mq 把长耗时部分分发出去分摊处理,但是大概率领导不让引入新的中间件,否则使用 flink 等实时处理可能更好,线程池目前扩大了,队列也增加了,但是还是偶尔会报警
    31 replies  •  2023-07-26 11:39:10 +08:00
    cvbnt
    cvbnt
    Jun 9, 2023 via Android
    1
    加内存
    zpf124
    zpf124
    Jun 9, 2023
    2
    处理速度跟不上只能增加性能,要么加内存要么加机器。

    治标的话,只为了不爆,那就改成把待执行队列存库,然后代码改成读取数据库,有数据就处理,弄成定时任务或者直接死循环。
    simple2025
    simple2025
    Jun 9, 2023
    3
    加线程数?
    iceshiny
    iceshiny
    Jun 9, 2023 via iPhone
    4
    找瓶颈
    thinkershare
    thinkershare
    Jun 9, 2023❤️1
    5
    CPU 密集任务你看加再多线程,加再多内存也没啥用。I/O 密集型,使用线程池就够了,反正 I/O 线程也不会被 CPU 调用,设个大点的数量就好了。你给的条件太有限,给不出你优化意见。
    kaneg
    kaneg
    Jun 9, 2023 via iPhone
    6
    如果是纯 IO 型的调用,可以上异步 IO ,不怎么消耗线程。

    如果不想增加异步 IO 的复杂性的话,就直接上最新版 Java 的虚拟线程,几乎可以无限开线程。
    yungo8
    yungo8
    Jun 9, 2023 via Android
    7
    任务放在线程池队列里,为什么会爆?
    hefish
    hefish
    Jun 9, 2023
    8
    请问如何在不加内存,不加 cpu 的情况,让电脑跑的快一些?
    yazinnnn
    yazinnnn
    Jun 9, 2023 via Android
    9
    执行接口指的是调用外部服务?
    io 密集的话可以用 netty 之类的 nio 客户端或者升级 jdk 用 loom
    cpu 密集的话没救
    dqzcwxb
    dqzcwxb
    Jun 9, 2023
    10
    串行改并行,同步改异步
    十字秘诀送给你
    xiangyuecn
    xiangyuecn
    Jun 9, 2023
    11
    ThreadPoolExecutor 线程池处理机制:
    1. 新任务进入核心线程执行(核心线程默认不回收)
    2. 核心线程数据量满了,放到队列等待
    3. 队列 TMD 也满了,开新线程处理,直到线程数量达到最大线程数(这种线程会回收)


    我一直没明白,这玩意到底是哪里会用到这破逻辑,最大线程数有个卵用啊😂

    按我的脑回路,应该是核心线程满了,就开新线程,直到最大线程数,最大线程满了就放队列等待
    hhjswf
    hhjswf
    Jun 9, 2023 via Android
    12
    Java 项目耗时基本在 io 上,最大线程数量可以搞大一点
    arloor
    arloor
    Jun 10, 2023
    13
    mq ,来积压在 mq 上,对于 kafka 是挤压在磁盘上
    dreamlike
    dreamlike
    Jun 10, 2023 via Android
    14
    先做热点采集 jfr 打个火焰图看看
    再分析下 perf 没数据不知道该怎么处理 也不清楚是什么样子的业务
    如果是那种你依赖的服务响应非常慢 直接上 reactive 来做 io 所占的也就几个闭包的内存,然后善用 timeout 和 buffer 来做被压就好了

    如果是依赖于 cpu 嗯算 那基本只能叠机器了 这种一般采集完信息会显示 cpu 占用平均值非常高
    keenkiller
    keenkiller
    Jun 10, 2023 via Android
    15
    MQ 啊
    RuralHunter
    RuralHunter
    Jun 10, 2023
    16
    客户端提交任务后定时查询任务状态
    服务端接到任务直接放队列,执行线程从队列取任务执行保存执行结果。同时相应客户端的查询状态请求
    tangAtang
    tangAtang
    Jun 10, 2023
    17
    @xiangyuecn 这是历史问题,以前 CPU 可没这么多核心
    hhjswf
    hhjswf
    Jun 10, 2023 via Android
    18
    @xiangyuecn 按你的脑回路最大线程数也没用啊,如果有源源不断的任务,你这最大线程数一直满载,我为什么直接加大核心数?
    someonedeng
    someonedeng
    Jun 10, 2023
    19
    用带持久化的 mq
    key0323
    key0323
    Jun 10, 2023
    20
    加个 kafka 自己发消息自己消费
    xiangyuecn
    xiangyuecn
    Jun 10, 2023
    21
    @hhjswf #18 直接加大核心线程数,不就等同于说明了最大线程数没卵用😂

    目前我就是这样做的,核心线程数 等于 最大线程数,通过设置 allowCoreThreadTimeOut(true)去掉核心线程这个概念,每个线程都是普通的,超时没有任务了线程就被回收,充分利用机器性能,其实也就等于说明了最大线程数没有卵用
    xiangyuecn
    xiangyuecn
    Jun 10, 2023
    22
    比如 核心线程数 等于 最大线程数 等于 100 个线程,核心线程空闲 5 秒关闭,队列给到 200 个容量

    假如大部分时候只需要 20 个线程工作就够了,偶尔会有 200 个突发任务

    那么一直会开启的可能就是 20 个左右的线程,突发的 80 个任务会开启新的线程处理,线程满了,多余的 100 个任务会被加入队列
    -------

    如果按照默认的逻辑,就算给到平常一倍核心线程数:40 个核心线程,200 个容量队列,100 个最大线程

    200 个突发任务工作是不正常的:只会有 40 个线程同时工作,160 个被加入队列,因为队列没有满,不会开启新线程!
    100 个最大线程成了摆设,队列卡在这个位置比较尴尬。
    wxxxcxx
    wxxxcxx
    Jun 10, 2023
    23
    异步编程应该很适合,不知道 java 有没有好用的库
    Red998
    Red998
    Jun 10, 2023
    24
    主要还是优化接口耗时问题、 从这方面入手。异步治标不治本,异
    rb6221
    rb6221
    Jun 10, 2023
    25
    如果你线程池都满了,那物理配置不加的话也没法再有很大的提升
    我的建议是换语言
    byte10
    byte10
    Jun 11, 2023
    26
    你的任务是 是什么任务啊,也没说清楚,是计算型的,还是 IO 密集型的?你的任务是要循环读取 mysql 数据进行处理吗?计算密集型,只能物理解决或者优化计算的算法。IO 密集型 加线程,4 核心 500 个线程都没问题。
    layxy
    layxy
    OP
    Jun 12, 2023
    27
    @kaneg 公司目前最高只让用 11,而且虚拟线程现在还没 release,还要升级到至少 java19,这个方案行不通
    layxy
    layxy
    OP
    Jun 12, 2023
    28
    @byte10 IO 密集型,排查了下,耗时集中在 es 查询
    layxy
    layxy
    OP
    Jun 12, 2023
    29
    @janus77 线程池满了,但是 cpu 占用不高,后续再加线程池大小再看看,最终的话引入 mq 应该是最好的,但是这个不好推进
    byte10
    byte10
    Jun 12, 2023
    30
    @layxy ES 支持异步的,你选一个 ReactiveElasticsearchTemplate 客户端 , 这样就不需要多线程了。不过你要注意的是 Reactive 通常会有背压问题,需要判断 ES 服务器能否抗住,扛不住就注意要限流,不然会导致 es 挂掉。
    zzw66681
    zzw66681
    Jul 26, 2023
    31
    单机可以换一下 disruptor
    About   ·   Help   ·   Advertise   ·   Blog   ·   API   ·   FAQ   ·   Privacy   ·   Solana   ·   1591 Online   Highest 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 60ms · UTC 23:08 · PVG 07:08 · LAX 15:08 · JFK 18:08
    ♥ Do have faith in what you're doing.