目前使用的线程池,但是因为任务量太大,单机线程池和队列很快就满了,因为某些原因只能使用一台机器,有什么办法可以优化下
1
cvbnt 2023-06-09 20:40:56 +08:00 via Android
加内存
|
2
zpf124 2023-06-09 20:55:49 +08:00
处理速度跟不上只能增加性能,要么加内存要么加机器。
治标的话,只为了不爆,那就改成把待执行队列存库,然后代码改成读取数据库,有数据就处理,弄成定时任务或者直接死循环。 |
3
chenqh 2023-06-09 20:58:54 +08:00
加线程数?
|
4
iceshiny 2023-06-09 21:01:49 +08:00 via iPhone
找瓶颈
|
5
thinkershare 2023-06-09 21:02:31 +08:00 1
CPU 密集任务你看加再多线程,加再多内存也没啥用。I/O 密集型,使用线程池就够了,反正 I/O 线程也不会被 CPU 调用,设个大点的数量就好了。你给的条件太有限,给不出你优化意见。
|
6
kaneg 2023-06-09 21:37:58 +08:00 via iPhone
如果是纯 IO 型的调用,可以上异步 IO ,不怎么消耗线程。
如果不想增加异步 IO 的复杂性的话,就直接上最新版 Java 的虚拟线程,几乎可以无限开线程。 |
7
yeqizhang 2023-06-09 22:00:36 +08:00 via Android
任务放在线程池队列里,为什么会爆?
|
8
hefish 2023-06-09 22:21:23 +08:00
请问如何在不加内存,不加 cpu 的情况,让电脑跑的快一些?
|
9
yazinnnn 2023-06-09 22:24:30 +08:00 via Android
执行接口指的是调用外部服务?
io 密集的话可以用 netty 之类的 nio 客户端或者升级 jdk 用 loom cpu 密集的话没救 |
10
dqzcwxb 2023-06-09 22:34:30 +08:00
串行改并行,同步改异步
十字秘诀送给你 |
11
xiangyuecn 2023-06-09 22:37:59 +08:00
ThreadPoolExecutor 线程池处理机制:
1. 新任务进入核心线程执行(核心线程默认不回收) 2. 核心线程数据量满了,放到队列等待 3. 队列 TMD 也满了,开新线程处理,直到线程数量达到最大线程数(这种线程会回收) 我一直没明白,这玩意到底是哪里会用到这破逻辑,最大线程数有个卵用啊😂 按我的脑回路,应该是核心线程满了,就开新线程,直到最大线程数,最大线程满了就放队列等待 |
12
hhjswf 2023-06-09 23:29:01 +08:00 via Android
Java 项目耗时基本在 io 上,最大线程数量可以搞大一点
|
13
arloor 2023-06-10 00:50:23 +08:00
mq ,来积压在 mq 上,对于 kafka 是挤压在磁盘上
|
14
dreamlike 2023-06-10 01:08:53 +08:00 via Android
先做热点采集 jfr 打个火焰图看看
再分析下 perf 没数据不知道该怎么处理 也不清楚是什么样子的业务 如果是那种你依赖的服务响应非常慢 直接上 reactive 来做 io 所占的也就几个闭包的内存,然后善用 timeout 和 buffer 来做被压就好了 如果是依赖于 cpu 嗯算 那基本只能叠机器了 这种一般采集完信息会显示 cpu 占用平均值非常高 |
15
tairan2006 2023-06-10 08:11:45 +08:00 via Android
MQ 啊
|
16
RuralHunter 2023-06-10 10:37:43 +08:00
客户端提交任务后定时查询任务状态
服务端接到任务直接放队列,执行线程从队列取任务执行保存执行结果。同时相应客户端的查询状态请求 |
17
tangAtang 2023-06-10 11:27:09 +08:00
@xiangyuecn 这是历史问题,以前 CPU 可没这么多核心
|
18
hhjswf 2023-06-10 13:19:44 +08:00 via Android
@xiangyuecn 按你的脑回路最大线程数也没用啊,如果有源源不断的任务,你这最大线程数一直满载,我为什么直接加大核心数?
|
19
someonedeng 2023-06-10 15:39:28 +08:00
用带持久化的 mq
|
20
key0323 2023-06-10 16:40:20 +08:00
加个 kafka 自己发消息自己消费
|
21
xiangyuecn 2023-06-10 17:07:00 +08:00
@hhjswf #18 直接加大核心线程数,不就等同于说明了最大线程数没卵用😂
目前我就是这样做的,核心线程数 等于 最大线程数,通过设置 allowCoreThreadTimeOut(true)去掉核心线程这个概念,每个线程都是普通的,超时没有任务了线程就被回收,充分利用机器性能,其实也就等于说明了最大线程数没有卵用 |
22
xiangyuecn 2023-06-10 17:18:37 +08:00
比如 核心线程数 等于 最大线程数 等于 100 个线程,核心线程空闲 5 秒关闭,队列给到 200 个容量
假如大部分时候只需要 20 个线程工作就够了,偶尔会有 200 个突发任务 那么一直会开启的可能就是 20 个左右的线程,突发的 80 个任务会开启新的线程处理,线程满了,多余的 100 个任务会被加入队列 ------- 如果按照默认的逻辑,就算给到平常一倍核心线程数:40 个核心线程,200 个容量队列,100 个最大线程 200 个突发任务工作是不正常的:只会有 40 个线程同时工作,160 个被加入队列,因为队列没有满,不会开启新线程! 100 个最大线程成了摆设,队列卡在这个位置比较尴尬。 |
23
wxxxcxx 2023-06-10 19:58:04 +08:00
异步编程应该很适合,不知道 java 有没有好用的库
|
24
Red998 2023-06-10 22:37:14 +08:00
主要还是优化接口耗时问题、 从这方面入手。异步治标不治本,异
|
25
janus77 2023-06-10 22:54:38 +08:00
如果你线程池都满了,那物理配置不加的话也没法再有很大的提升
我的建议是换语言 |
26
byte10 2023-06-11 09:29:16 +08:00
你的任务是 是什么任务啊,也没说清楚,是计算型的,还是 IO 密集型的?你的任务是要循环读取 mysql 数据进行处理吗?计算密集型,只能物理解决或者优化计算的算法。IO 密集型 加线程,4 核心 500 个线程都没问题。
|
27
layxy OP @kaneg 公司目前最高只让用 11,而且虚拟线程现在还没 release,还要升级到至少 java19,这个方案行不通
|
29
layxy OP @janus77 线程池满了,但是 cpu 占用不高,后续再加线程池大小再看看,最终的话引入 mq 应该是最好的,但是这个不好推进
|
30
byte10 2023-06-12 14:05:50 +08:00
@layxy ES 支持异步的,你选一个 ReactiveElasticsearchTemplate 客户端 , 这样就不需要多线程了。不过你要注意的是 Reactive 通常会有背压问题,需要判断 ES 服务器能否抗住,扛不住就注意要限流,不然会导致 es 挂掉。
|
31
zzw66681 2023-07-26 11:39:10 +08:00
单机可以换一下 disruptor
|