看到有个帖子在讨论 Java 异步 技术栈的问题... 由于今天台风不能送外卖,所以我也来分析分析..

2021-07-26 16:34:34 +08:00
 yizmaoaa

看到有个帖子讨论 Java 目前实现全链路异步的帖子

目前全异步的技术栈大概有

1.SpringWebFlux+Reactor+R2DBC(很久没有了解过了,不知道 Spring 还有没有支持其他服务的一些 Client)

2.Vertx+Future/Vertx+RxJava/Vertx+Mutiny/Vertx+Coroutines

3.Micronaut

4.Quarkus

Vert.x 的 Future 以及 RxJava/Mutiny/Reactor 其实这几个都差不多,基本上在异步技术栈里都是为了解决 CallBack 的问题

主要还是 Jdk 本身的 Future 太拉稀,结果现在每家都自己搞了一套...也是挺蛋疼的

SpringWebFlux/Micronaut/Quarkus 算是比较上层的大杂烩框架了。三家写起来其实都差不多。差别在于 Micronaut/Quarkus 主打的无反射 /云原生。总体打包镜像与内存占用都是比较小的

目前 SpringWebFlux 与 Micronaut 都比较依赖于第三方的 Client 实现,如果第三方的 Client 实现是阻塞的,那么对于 Micronaut 与 WebFlux 来说实际上并不能提高多少吞吐的。

对于 Quarkus 来说,由于 Quarkus 算是在 Vert.x 上面在来了一层,所以 Vert.x 自己实现的各种 Client 在 Quarkus 中也是能用的。比 Micronaut 与 WebFlux 要稍微好那么一丢丢

不过 Micronaut 其实也能用 Vert.x 的 Client,但是效果貌似一般。主要我觉得可能还是 2 套 EventLoop 的问题,不能自上而下的用一套。

理论上 WebFlux 也能用 Vert.x 的各种 Client,但是我觉得效果应该和 Micronaut 差不多。我也不太确定到底麻烦不麻烦。

Micronaut 的 SqlClient 是支持 Vert.x 这边的(之前是我提交的)

另外 Vert.x 这边基本上所有的 Client 都是自己根据协议写的,所以基本上是可以做到全链路异步的。但是碰到官方没有支持到的 Client 那么做法其实与上面的一些东西差不多了

如果你是频次较高的去操作这些没有异步支持的 Client,那么吞吐量还是同样的不尽人意的。所以这也是在做技术选型的时候需要考虑的一点。

如果你对性能的要求没那么高,但是希望内存占用小那么可以选择 Quarkus/Micronaut 两位都支持同步的写法。

如果你对性能要求高,不排除异步的写法那么你可以选择 Vert.x

不管怎么来说或者你用那个,用 Java 写异步的代码都是有点蛋疼的。

相对来说 Vertx+Kotlin Coroutines 要舒服很多,切换到 Kt 的成本也相对的没那么大。

另外目前我是不推荐使用 SpringWebFlux 或者 Micronaut 的异步写法的。

在 TechempoerBenchmarks 最新一轮的性能测试中,这两位的表现并不出色

https://www.techempower.com/benchmarks/#section=data-r20&hw=ph&test=db

如果你用了异步这种麻烦的写法,但是实际上并没有性能的提升,这是划不来的。

引入了异步写法的唯一目的就是希望在同样的服务器上能承受更大的吞吐。

如果引入了异步 /提高了代码的复杂性以及可维护性并没有换回来性能的提升,这是得不偿失的。

另外,异步所能解决的问题,同步同样能解决(只不过是加多少机器的问题...)

6276 次点击
所在节点    Java
52 条回复
zoharSoul
2021-07-26 16:58:55 +08:00
说的很中肯,
顺便补充一下, quarkus 的 native image 非常节省内存, 甚至有一个数量级的差别
Ariver
2021-07-26 17:05:12 +08:00
感觉 java 这个推不动。
从这几年的发展来看。
yizmaoaa
2021-07-26 17:09:44 +08:00
@Ariver 是的,我也觉得。就算 Loom 出来。到大家能接受用上都不知道是多少年后了
tt0411
2021-07-26 17:34:33 +08:00
对中小公司来说, 全异步带来的性能提升价值没那么大, 大公司对性能敏感的服务直接原生语言了: 只能说 Java 面向的场景不是这块
ikas
2021-07-26 18:34:49 +08:00
java 异步方案现在很多.

单说代码层面,现在缺失的是统一的规范
虽然有类似 Promise 的 CompletableFuture,但是目前只有内置的 httpclient,jax-rs 等少量库提供这样的接口;
也有 flow 这样内置的响应式接口,但是同样太过简单...大部分响应式也都是自己定义接口..

即使是最新的 project-loom 提供了虚拟线程,也并未提供语言层面更简化异步代码编写的方案,或者需要其成熟以后,太遥远

没有一个好的方便的异步语法 /统一接口,其他再多的异步库,用起来也还是蛋疼...
x940727
2021-07-26 19:06:31 +08:00
@zoharSoul 编译速度太慢了,差不多要 8G 内存,5 分钟,有点受不了……
securityCoding
2021-07-26 19:30:12 +08:00
老哥,你技术水平明显不低,送外卖补贴家用吗?
yizmaoaa
2021-07-26 20:00:01 +08:00
@x940727 Native-Image 的打包速度属实挺难受
yizmaoaa
2021-07-26 20:00:22 +08:00
@securityCoding 老哥客气了, 我水平属实也不高
liuxu
2021-07-26 20:13:56 +08:00
抓哇程序员一般是美团还是饿了么,下次我点个帮我改下 bug
yizmaoaa
2021-07-26 20:31:58 +08:00
@liuxu 都跑,众包
golangLover
2021-07-26 22:33:44 +08:00
借楼问一下,现在服务器端 api 请求远程 api 的话主要还是用 completablefuture+rest template 吗。还是有其他推荐?
QZFCANBA
2021-07-26 22:48:46 +08:00
@golangLover #12 顺便问一下,completablefuture+rest template,这套实际应用有啥坑吗?
daimubai
2021-07-26 22:52:39 +08:00
老哥一般跑哪个时间段
MarkLeeyun
2021-07-26 23:40:27 +08:00
老哥有空帮我改个 bug 吗?我这就点外卖。美团还是饿了么
ljzxloaf
2021-07-27 08:41:48 +08:00
老哥,跑外卖怎么入门
Rwing
2021-07-27 09:43:08 +08:00
各位 java 大佬,何不尝试一下 c#?
await HttpClient.GetAsync("https://www.v2ex.com")
yizmaoaa
2021-07-27 09:57:45 +08:00
@daimubai 全跑
yizmaoaa
2021-07-27 09:58:05 +08:00
@MarkLeeyun 你干的这是人事吗
dk7952638
2021-07-27 10:02:00 +08:00
reactor-netty 和 rsocket 怎么样,老哥有了解么

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

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

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

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

© 2021 V2EX