spring webflux 在哪些环节是异步的?

2022-06-07 14:50:28 +08:00
 czd670
对于 webflux ,我的理解是在网络请求响应的时候,使用异步 IO ,基于 io 多路复用,提升系统吞吐量。在 controller 中,比如线程把 HttpRequest 给到 controller ,然后马上返回去处理其他任务,不用等待业务代码的执行。

我的疑问
1 、在我的业务逻辑中,使用到的数据库操作,也必须是异步非阻塞的吗?比如目前提供的 redis 、mongodb 、mysql 的支持库。还是说,其实这些异步库,可以用传统的同步阻塞方式去操作磁盘 IO 。(这样子做,webflux 的优势只发挥在网络请求的那部分)
2 、这些异步支持库,本质上是不是类似 nio ,通过监听 IO 事件,然后 attach handler 来完成整个业务逻辑?
1522 次点击
所在节点    Java
8 条回复
byte10
2022-06-08 11:53:20 +08:00
第一个问题:使用数据库操作必须是 非阻塞的, 有同步非阻塞和异步非阻塞,都可以。这些异步库 操作磁盘 IO 没听明白。这些数据库的异步库代码一般都是网络 IO ,应该不涉及到写磁盘 IO 。
第二个问题:本质是 NIO ,用 NIO 客户端。

第三个:但是 mysql 的通信协议 可能不支持多路复用(我没确认过),这里的多路复用是指协议上的多路复用(非 NIO 那种概念)。这个多路复用,就是在一个 TCP 连接中可以存在多条流。http2 支持多路复用,http 不支持。也就是说即便用上 NIO 也未必能带来更大的吞吐量,需要同时调整 http 连接数。同理 mysql 也可能会在连接数出现瓶颈。请求的数据可能会堆积在服务端。

第四个,由于是响应式编程,注意下背压的问题,保护好下游的服务。
czd670
2022-06-09 14:17:14 +08:00
@byte10 这几天重新学了 nio 和 netty ,敲了代码。第二点基本懂了。关于第一点 webflux 操作 mysql 的问题,你指的是不是:与 mysql 的网络 io 操作,也是利用 nio 来实现?
流程大概是:提交 io 事件、nio 写事件、nio 读事件,设置 handler 来处理 mysql 的返回数据?但是这个异步能力,需要提供 mysql 异步组件,例如现在的 r2dbc
czd670
2022-06-09 14:18:28 +08:00
@byte10 还有个疑问,第一个问题,说使用数据库必须用非阻塞。我的理解是,在 webflux 里面,非阻塞只应用在接受请求发出请求。数据库操作,我还是在工作线程里面使用阻塞 io 也是可以的吧?
byte10
2022-06-09 16:36:04 +08:00
@czd670 是的,需要用 r2dbc 。 “我的理解是,在 webflux 里面,非阻塞只应用在接受请求发出请求。数据库操作,我还是在工作线程里面使用阻塞 io 也是可以的吧?” ,不是很理解你表达啥。工作线程 使用阻塞 IO 是不行的。性能会严重 下降
czd670
2022-06-09 17:14:19 +08:00
@byte10 我知道性能会下降,我的意思是,代码上这样做是可以的,只是会影响性能。我了解到的是,传统 jdbc 因为是基于线程来开发的,也就是事物等机制需要绑定线程,所以做不到异步 io ,但不代表不能用?
byte10
2022-06-09 20:14:00 +08:00
@czd670 呢可以的,建议用线程池去 执行同步 IO ,这样不会损失太多的性能。
czd670
2022-06-09 23:42:45 +08:00
@byte10 的确,不过真要用 webflux ,肯定是用异步 io 的方案
ychost
2022-06-10 11:30:04 +08:00
主要看驱动,MySQL 也有支持异步的 R2BC 等等,其余的网络,文件等操作都是直接支持的,底层应该是系统的 epoll 和 SELECT

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

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

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

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

© 2021 V2EX