1
ch2 2021-04-28 18:13:16 +08:00 1
异步的协程不是真正的线程,你可以理解为开成千上万个对机器性能的压力都是毛毛雨
多线程是可以达到一样的效果,但是额外的 CPU 跟内存开销大了很多 并且多线程还容易出 bug 不好调试,代码逻辑更是无端变复杂了很多 改成异步之后你单个线程一秒钟就可以发一千个请求毫无压力,直接一个就能顶一千个线程 你还可以开 n 个线程,每个线程都用异步 buff 可以叠加何乐而不为? |
2
yumenawei OP |
3
ikas 2021-04-28 21:30:28 +08:00 1
http 异步是让你减少 cpu 的浪费,再等待结果的过程中,可以继续执行其他的调用
|
4
BBCCBB 2021-04-28 21:57:46 +08:00 1
future.get 还是会阻塞住, 完全异步应该是要针对 future 加个 listener 回调, 在回调里处理. 可以用 reactor 这种写法. 或者 CompletableFuture..
|
5
micean 2021-04-28 22:23:19 +08:00 1
vertx 的 httpclient 同样也是使用线程池,future.get 应该是 java.util.concurrent 包里的
异步只是为了提醒和帮助你更好的使用非阻塞,减少线程数。 大多数实际场景异步同步的性能差距并不太明显。 |
6
cloud107202 2021-04-28 23:21:12 +08:00 1
使用异步的服务伸缩性更好,比如 spring boot 同步的 web 需要预估请求量来配置线程池的最小最大值。
最大值配小了遇到高峰请求服务不过来,高峰过了又在 pool 里空等 |
7
kaneg 2021-04-28 23:49:10 +08:00 1
单纯的异步用线程池就可以,但要极大地提高性能,底层的 http 客户端应该要用 NIO 才行。
|
8
ipwx 2021-04-29 00:00:09 +08:00 1
1. 用 future.get 就错了。
2. https://www.v2ex.com/t/772976#reply28 |
9
wqhui 2021-04-29 09:27:08 +08:00 1
http 请求发送完成到接到响应这过程是主要耗时,在你用 get 阻塞之前还能多发几个 http 请求,同时等待响应。如果说线程池内的线程表现更好,有两个可能,一是响应是靠回调的,就是三楼说的 listener 写法,不需要阻塞(按你自己的阻塞写法,理论上是会有时间浪费在那);二是线程复用
|
10
gaius 2021-04-29 09:41:24 +08:00 1
用 webflux 的 webclient
|
11
yumenawei OP @ikas #3 感觉只是一部分原因,结果的获取仍然需要有人去执行,这个地方仍然会用 cpu
@BBCCBB #4 这个地方我们可能没有处理的太好,后面研究下 @micean #5 我往下看了下,vertx 好像用了 netty 做了客户端的 nio,不大确定,还在看,老哥了解吗? @cloud107202 #6 那这个也不是伸缩性好吧?而是性能和处理效果更高? @kaneg #7 看了下,好像底层是用的 netty 做的客户端 nio,还在看,感谢提供思路 @ipwx #8 感谢分享。因为服务需要调用的结果,所以用的 future.get ,请问正确的用法是? @wqhui #9 感谢,应该是底层用了客户端的 nio 来处理请求,提升性能 @gaius #10 老哥,应该是与框架没太大关系,我想了解的是上了这个框架,为啥性能和效果更高。 |
12
BBCCBB 2021-04-29 14:08:32 +08:00
为啥性能更好这个..
可以参考传统的网络编程, 一个线程处理一个连接, 大部分时间都没有读写, 线程经常在睡眠和睡眠状态来回切换, 大量时间和 cpu 花在 context swtich 上, 而 nio 这种. 一个或几个线程就能处理大量连接, context switch 很少,能把 cpu 利用起来 |
13
unco020511 2021-04-29 16:06:05 +08:00
jvm 没有协程,所以基于 jvm 语言的协程 api 都是用的线程
|
14
7075 2021-04-29 17:41:27 +08:00
可以参考一下 icop 模型和 epoll 模型,
异步的本质就是不浪费机器资源在阻塞上。 |
15
micean 2021-04-29 21:42:08 +08:00
@yumenawei
vertx 本来就是 netty pro,无论是线程还是 Buffer 都是对 netty 的封装,Vertical 和 Context 那一套保证线程安全的东西才是属于 vertx 的 |
16
passerbytiny 2021-04-30 09:54:46 +08:00 via Android
异步的重点不是线程池 /协程( Java 只有线程池没有协程),而是多任务切换。
你这个总是使用 future.get ,等同于同步调用(虽然比常规同步会好那么一丁点),并不能提高并发能力。要用到 listener 才能发挥异步的真正实力。 |
17
ikas 2021-04-30 16:56:37 +08:00
@yumenawei 你要把异步 io 与线程池 /线程这些分开去想 .假设你用异步 io 的 httpclient,那么你可以在一个线程中调用这个 client10 次,然后在这个线程中使用 get 等待.如果你用同步 io 的 httpclient,那么你要实现这样,就是要开 10 个线程,那如果更多呢
|
18
yumenawei OP @micean #15 感谢指导。
@passerbytiny #16 嗯嗯,还有就是请求用了 nio,不用一个线程一直等待结果。 @BBCCBB #12 当初没想到客户端也可以用 nio @ikas #17 是,我被异步这个东西限制住了思考 |
19
CantSee 2021-05-12 18:20:51 +08:00
通过线程池进行多线程调用时,业务代码是并行的,但是在 future.get 是阻塞的吧()
|