V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
tctc4869
V2EX  ›  Java

如果要在 Spring webflux 和 Vert.x web 选一个,在不仅仅只考虑性能的情况下,选哪一个

  •  1
     
  •   tctc4869 · 2020-05-20 17:32:35 +08:00 · 11162 次点击
    这是一个创建于 1408 天前的主题,其中的信息可能已经有所发展或是发生改变。

    在 Spring webflux 和 Vert.x web 的两种都有基于 netty 的响应式 webmvc 框架选一个,在不仅仅只考虑性能的情况下,(例如灵活可扩展性,多种可能的开发方式选择)等,各位会选择哪一个?

    除了 Spring webflux 和 Vert.x web,还有哪些呢?

    第 1 条附言  ·  2020-05-20 20:12:41 +08:00
    我看了一下 vert.x 的演示代码,在 action 那一块,

    System.out.println("开始之前");
    HttpServer server = Vertx.vertx().createHttpServer();
    Router router = Router.router(Vertx.vertx());
    router.route("/index").handler(request -> {
    request.response().end("INDEX SUCCESS");
    });

    router.route("/test").handler(request -> {
    request.response().end("test");
    });
    server.requestHandler(router::accept);
    server.listen(5555);
    System.out.println("开始之后");

    router.route("/test2").handler(request -> {
    request.response().end("test222");
    });

    这端代码意味着,vert.x web 能动态创建 action,这个特性还是很棒的,虽然 spring 的拦截器,jfinal 等已经具备了动态路由方向配置功能
    第 2 条附言  ·  2020-05-20 20:17:59 +08:00
    我其实并不是很关心有没有异步,我想了解一下,除了异步,spring webflux 和 vert.x web,还有其他的哪些特性。spring webflux 的主要特点,不会就只有异步吧?
    第 3 条附言  ·  2020-05-20 22:21:48 +08:00
    使用 vert.x, 要用异步驱动 jdbc 来访问数据库再能保持良好的性能么,不然性能会比传统阻塞式性能还差?难道在 vert.x 里用传统的 jdbc 驱动读取数据库会有性能问题(相对于传统)?
    第 4 条附言  ·  2020-05-21 16:48:54 +08:00
    vert.x 有基础库,这意味着自己可以定制处理流程,这点也不错
    83 条回复    2020-06-26 13:17:09 +08:00
    wangyanrui
        1
    wangyanrui  
       2020-05-20 17:38:40 +08:00
    Java 狗,选择 Spring webflux,因为文档多! doge
    tctc4869
        2
    tctc4869  
    OP
       2020-05-20 17:54:05 +08:00
    @wangyanrui Spring webFlux 具备动态创建或移除一个 Action 实例的功能么?
    我在浏览了一下某个博客的 vert.x web 讲解,在 action 那个例子看了一下,好像 vert.x web 能动态创建 action 实例,虽然我还没用的,如果真是这样的话,那这也是很好的。
    hangszhang
        3
    hangszhang  
       2020-05-20 19:07:50 +08:00
    @tctc4869 动态创建有什么意义吗?
    tctc4869
        4
    tctc4869  
    OP
       2020-05-20 19:21:22 +08:00
    @hangszhang 动态创建的意义么,一两句话说不清楚,可以看一下这个帖子描述的问题,https://www.v2ex.com/t/671933#reply11
    YUyu101
        5
    YUyu101  
       2020-05-20 19:34:21 +08:00
    reactor 用不惯,vertx 用 kotlin 还行
    Kaiv2
        6
    Kaiv2  
       2020-05-20 19:38:10 +08:00 via Android
    没用过 Spring webflux 这种异步响应式的开发模式,不过选 Spring webflux 遇到问题应该比较好解决,文档博客都比较多。

    动态配置 action 的场景没遇到过,个人的实现思路,可以在数据库中建一张 action 配置表,Java 代码动态解析。
    dcalsky
        7
    dcalsky  
       2020-05-20 19:40:51 +08:00 via Android
    为 vertx 投一票 开发起来很爽
    optional
        8
    optional  
       2020-05-20 19:43:33 +08:00 via Android
    还有 quarkus
    tctc4869
        9
    tctc4869  
    OP
       2020-05-20 19:45:20 +08:00
    @Kaiv2 动态 action 配置需要 mvc 框架有两个其中之一的可选关键配置,路由动态配置,动态 action 创建。不知道 java 现在的 mvc 框架除了 spring 拦截器和 jfinal (动态路由配置),还有哪些 mvc 提供这些功能。
    路由方向改变,也就是我把请求 /test/add 在后端被检测到后,改成 /genaral/add 。响应 /genaral/add 的内容
    另一个就是动态创建 action 实例了。
    avalon0624
        10
    avalon0624  
       2020-05-20 19:54:18 +08:00
    如果从长远维护来看,建议是 Spring webflux 。Vertx.x 更新得还是比较激进的。
    sagaxu
        11
    sagaxu  
       2020-05-20 20:02:43 +08:00 via Android
    webflux 生态比 vertx 差不少
    tctc4869
        12
    tctc4869  
    OP
       2020-05-20 20:06:25 +08:00
    @sagaxu 差? webflux 不是 Spring 的么,基于 spring 的组件还是有很多
    liuxey
        13
    liuxey  
       2020-05-20 20:11:10 +08:00
    @tctc4869 #12 然而 spring 的其他组件比如 data 和连接池系列大都是同步 api,webflux 无用武地,我觉得没必要为了异步而异步
    tctc4869
        14
    tctc4869  
    OP
       2020-05-20 20:16:48 +08:00
    我其实并不是关系有没有异步,我想了解一下,除了异步,spring webflux,还有其他的哪些特性。spring webflux 的特点,不会就只有异步吧?
    yazinnnn
        15
    yazinnnn  
       2020-05-20 20:31:48 +08:00
    请问 vertx 如果使用异步 api 存储数据的话,相较于普通同步存储数据(比如存到 mysql 或者 redis),有什么优势呢? 支持背压?
    STRRL
        16
    STRRL  
       2020-05-20 20:39:22 +08:00 via Android
    vertx
    chendy
        17
    chendy  
       2020-05-20 20:47:10 +08:00
    @liuxey #13 data 也就 jdbc 需要用 r2dbc 来异步,其他都有原生异步…
    hantsy
        18
    hantsy  
       2020-05-20 20:48:30 +08:00
    喜欢 Vertx 就用 Quarkus 吧,它深度集成了 Vertx 。使用 GraalVM Native Image 来 Build Docker Image, Docker 启动时间至少会缩短一个数量级。

    之前的用简单的 CURD 带数据库 REST API 测试,启动时间可以达到 0.3 S 内。而相应的 Spring Boot 程序却要大约 10 S 左右。https://medium.com/@hantsy/kickstart-your-first-quarkus-application-cde54f469973

    https://github.com/hantsy/quarkus-sample

    有其它的很多文章测试,还有 Quarkus 首页的比较,运行时效率也会大大提高。

    但是,Quarkus 也有一些限制,由于全部走编译处理,所以 CDI API 并没有完全实现。API 使用必须参考官方文档。另外 ,Building GraalVM Native Image 是个很费时的事情,开发时没有必要编译,可以用 CI 服务做这个工作。

    Spring 也在开始着手支持 Graal,目前离产品环境使用尚早,Spring 太多的依赖运行时处理。
    voidxx
        19
    voidxx  
       2020-05-20 20:54:29 +08:00 via iPhone
    webflux 到底有什么鸟用?
    hantsy
        20
    hantsy  
       2020-05-20 21:00:03 +08:00
    CoderGeek
        21
    CoderGeek  
       2020-05-20 21:02:51 +08:00
    webflux rxjava ?说实话都用的少
    hantsy
        22
    hantsy  
       2020-05-20 21:12:26 +08:00
    @chendy 目前 R2dbc 还不能完全代替 Jdbc 。在 Spring Data 下,Spring data jdbc 可以说是一个轻量的 ORM 框架了,Spring Data R2dbc 基于全新的 R2dbc 协议,协议范围也没有完全替代所有的 JDBC 功能。比如很现实的一个例子,Spring Data Jdbc 可以操作表关联关系,Spring Data R2dc 还不能。目前 Spring data jdbc 和 Spring data R2dbc 共享了部分代码,但是很多东西在项目处理棘手,例如对于维护数据库,怎么处理 Flyway (依赖 Jdbc 协议)等, 与 R2dbc 协作也变成困难了。
    hantsy
        23
    hantsy  
       2020-05-20 21:31:40 +08:00
    @sagaxu WebFlux 只是 Spring 造出来一个词。基本上 Spring 自己的生态可以全部使用了。

    Vertx 相对还是比较小众化,它的 Rective PgClient 我试用过,实在有点吃力,长期没写 JDBC,那个操作和 JDBC 一样原始。Quarkus 也集成了 Vertx 的 PgClient,MySQlClient Reactive 操作,不过现在 Hibernate 下新开了一个 Hibernate Rx 项目,利用大家熟悉的 JPA/Hibernate API (主要是保留同样的 Annnotations 使用) 重新实现 Reactive 功能。

    目前几乎所有(当然还有少量没有 Reactive 版本的)的以前传统的 Spring API 都有 Reactive 版本。Spring Webflux 基本可以在项目开发中代替传统的那一套以 Spring WebMvc 为基础 API 。
    hantsy
        24
    hantsy  
       2020-05-20 21:46:58 +08:00
    @liuxey Spring Data 下的项目从 Spring 5.0 加入 WebFlux 模块时,一开始就有 NoSQL 支持 Reactive Streams,比如 Mongo,Redis 是最早提供 Reactive 驱动的,现在常用的 NoSQL 有 Reactive 支持,包含 Casandra,ElasticSearch,Couchbase 等,这些在 Spring Data 都有提供 Reactive 版本。

    现在 RDBMS 也通过 Spring Data R2dbc (目前流行关系数据库都提供了 R2dbc 驱动)解决 RDBMS 的 Reactive 实现问题了。Spring Data R2dbc 1.0 刚进入 Spring Boot 2.3 Release train.
    lhx2008
        25
    lhx2008  
       2020-05-20 21:51:46 +08:00
    生产环境不要用,特别是 webflux,性能提高并不是那么明显,但是代码可读性,面向对象的能力,扩展性,可维护性都扑街,还有各种坑等着你。
    最简单的,异步整合三个数据源,三个数据源用回调函数返回数据,你怎么写回调串一起?有一个报错了你怎么处理怎么重试?下次要删掉一个呢?
    WispZhan
        26
    WispZhan  
       2020-05-20 21:54:43 +08:00
    看来只有我选 Ktor 这个异端?

    不管是 WebFlux 还是 Vertx,你的数据库驱动必须要有良好的异步支持,不然性能比传统的阻塞式 mvc 还差。
    chendy
        27
    chendy  
       2020-05-20 23:23:03 +08:00
    自己玩的话,随意
    公司项目的话,都不用
    yizmaoaa
        28
    yizmaoaa  
       2020-05-21 00:40:50 +08:00
    作为一个为 Vert.x 贡献过一点代码人。

    在不考虑性能等情况下 WebFlux 和 Vert.x 都不要用

    Webflux 表面看起来生态齐全,但是其大部分生态都是阻塞的客户端外面套一层壳。所以性能看起来与传统 SpringBoot 差别真心不大。

    Vert.x 除非你比较强,或者说项目真的并发比较大,否则也是不太建议你使用 Vert.x

    Vert.x 4 后所有的异步操作默认都返回了 Future 。所以开发也比较方便,另外就是你用 Kt 的话也会比较舒服。

    相对于 Spring 家的来说,Vert.x 不是框架,而是工具。官方开发人员就那么多。维护每个中间件的 Client 已经比较累了

    所以 Vert.x 的一些 Client 都很原始。并没有太多的精力在去开发框架。Vert.x 的官方人员只负责给你写一个基础协议通信的 Client 、想要更简单的开发还是需要自己写很多东西。

    所以如果你的某些项目业务不复杂,而且并发高。那么用 Vert.x 是一个很好的选择

    反之你的项目业务流程比较复杂,并发不高。大量的 CRUD 。我还是建议你使用传统的 SpringBoot 。开发速度更快。配套设施也齐全

    再着回答一下第三条附言,要用异步驱动 jdbc 来访问数据库再能保持良好的性能么,不然性能会比传统阻塞式性能还差?

    这里不得不说一下 Vert.x 下关于访问数据库的两个项目,一个是传统 JDBC 外套一个壳子的 Vertx-JDBC 。一个是完全异步的 SQL-Client 。 比传统阻塞性能还差是不存在的。只不过确实会因为传统的 JDBC 占用的大量的连接会导致吞吐量上不去。但是总体来说也是比 Springboot 强不少

    另外,其实对于这种玩意来说,大吞吐量下必然情况是大多数访问打进来是打到缓存层的 Redis 啊之类的。这种就特别适合 Vert.x 。代码量少。性能高。不必纠结 SQL 问题。

    你说的不考虑性能的情况下,完全操作就是基于传统数据库,那么这种比较原始的 SQL-Client 写起来是非常蛋疼的。
    araaaa
        29
    araaaa  
       2020-05-21 01:58:15 +08:00 via iPhone
    vertx➕ spring reactor
    tctc4869
        30
    tctc4869  
    OP
       2020-05-21 08:27:33 +08:00
    @yizmaoaa

    @YUyu101
    kt? Kotlin ?
    用这个做 Vert 开发比 java 用 vert 开发 舒服么?舒服在哪?代码好看便于阅读么?
    sagaxu
        31
    sagaxu  
       2020-05-21 09:42:19 +08:00 via Android
    @tctc4869 用了 Kotlin 就是协程那套了,不再需要回调套回调,也不需要 then 套 then 了,reactive 那套写法只适合平铺直叙,循环中带点分支就开始绕了。

    @hantsy 能用和按照异步方式重新设计差别还是很大的,原生异步支持的协议是不是够全,自己开发私有协议实现是不是方便
    zoharSoul
        32
    zoharSoul  
       2020-05-21 10:32:34 +08:00
    我选 vertx 起码比 spring webflux 成熟
    hantsy
        33
    hantsy  
       2020-05-21 10:39:06 +08:00
    @sagaxu 我倒觉得恰好相反,对于 REST API,本来就是数据流的处理,用 ReactiveStreams API 感觉很亲切,异常另外一条路径返回结果就好了。

    Kotlin 在 Spring 值得使用,很多配置都是 Kotlin DSL 扩展。https://github.com/hantsy/spring-kotlin-dsl-sample/blob/master/webmvc/src/main/kotlin/com/example/demo/DemoApplication.kt#L45-L75

    协程在 Spring 文档中并没有太多提到如何控制,以前看过 Android Kotlin 开发一点教程,UI 和后端 IO 都用不同的 Dispatcher 来调节。
    yizmaoaa
        34
    yizmaoaa  
       2020-05-21 10:51:04 +08:00
    @tctc4869 就是开发速度和阅读性,Vert.x 自带了 Promise/Future 。但是在 4.0 之前 所有 API 默认都是 callback 那一套。

    自己为每个 API 封装个 Future 太蛋疼了,要么就只能选择 RxJava 。

    4.0 之后,每个 API 都原生返回 Future 了,操作起来就比较方便。

    用 Kotlin 的好处就是 Vert.x 的 Kt 包是封装了 API 了。每个异步操作都是 XXXAwait 。和写传统都代码区别不大了。

    Future 和 Rxjava 那套对同事以及个人水平都是有要求的。很容易把代码组织成 shi 。。。
    yizmaoaa
        35
    yizmaoaa  
       2020-05-21 11:01:28 +08:00
    另外再补充一下,Quarkus 也不错可以考虑考虑,就是用的人少点,这两个项目都算是红帽的。而且两个项目的核心开发者与 Graalvm 都交流挺密切的。另外 Vert.x 也利用 Graalvm 衍生出了 ES4X 这个项目。

    另外如果真想 WebFlux 与 Vert.x 中做技术选型的话 我还是比较推荐 Vert.x 的

    主要还是我觉得国内开发者参与 Vert.x 项目不少,因为前几届的谷歌夏令营项目 Vert.x 都有参与的。

    而且好几个参与 Google 夏令营的国内开发者参与了 Vert.x 的一些子项目开发。

    例如从去年开始出的 Vert.x-sql-client 就是国内的开发者开发的。

    参与了 Vert.x 项目贡献的人也不少。虽然我也仅仅是修复了 Vert.x 的一些简单的 BUG 。

    也就是说假如你使用 Vert.x 出了一些紧急问题,那么你提个 Issues,或者群里发一下问题,可能没多久就能解决掉

    对于 Webflux 和 R2dbc 来说,我没太关注。不知道有没有国内的开发者贡献过代码所以出了问题很可能只能等官方解决。
    tctc4869
        36
    tctc4869  
    OP
       2020-05-21 11:01:54 +08:00
    @yizmaoaa 4.0?

    4.0.0-milestone?
    tctc4869
        37
    tctc4869  
    OP
       2020-05-21 11:05:16 +08:00
    @yizmaoaa
    我看了一下 maven 上关于 vert.x jar 版本的发布时间
    4.0.0-milestone 是 2019 年出的,
    而 3.9.0 是 2020 年出的。
    3.9 与 3.9 以前的有什么区别么,3.9 与 4.0 相比呢
    yizmaoaa
        38
    yizmaoaa  
       2020-05-21 11:05:53 +08:00
    @tctc4869 是的,4.0 目前还没有正式发布。具体发布时间我也不太清楚。假如后面的项目要用 Vert.x 我还是建议直接使用 4.0 。因为 4.0 更改的东西蛮多的。之前有个朋友已经直接使用 4.0 第 4 个里程碑版本 在正式环境了。
    yizmaoaa
        39
    yizmaoaa  
       2020-05-21 11:17:32 +08:00
    @tctc4869 4.0 在 3.8 的时候就开始做了,3.9 是有一些小更改。基本都是 BUG 修复之类的。3.8 的一些变动基本上就是为了 4.0 做准备的。比如以前都是 Future 负责生产和消费。3.8 改了实现,新增了 Promise 负责生产、Future 负责消费。

    4.0 的更新就比较多了,所有 API 都默认返回 Future,还有就是以前官方建议所有的第三方客户端,例如 Mysql 、HttpClient 、Redis 都是每个 Verticle 创建自己的。4.0 之后 Vert.x 将这些客户端在获取连接或者执行时都绑定在了一个 Context 上,所以可以多个 Verticle 去共享一个 Client 。 还有就是 Json 处理 Jackson 不在是强制的了,可以替换为任意一个 Json 实现。

    这些是比较大的变化,其他的你可以参考 Vert.x 的 Break Change

    https://github.com/vert-x3/wiki/wiki/4.0.0-Deprecations-and-breaking-changes
    yizmaoaa
        40
    yizmaoaa  
       2020-05-21 11:22:56 +08:00
    @tctc4869 还有就是增加了一个 SQL-Template 。写 SQL 能稍微方便点,目前 SQL-Client 的 PG 与 Mysql 部分总体已经完事。4.0 应该还要等 mssql 与 db2 的实现完成才会发布。4.0 应该还会发布 opentracing 与 zipkin 与 Vert.x 的集成。

    总的来说,3.8 与 3.9 以及后面所发布的 3.x 改动基本上都不大了。4.0 是一个大版本。所以才会在 19 年就开始发布里程碑版。
    tctc4869
        41
    tctc4869  
    OP
       2020-05-21 11:27:03 +08:00
    @yizmaoaa 大神,我还想问一下关于 vert.x 做 tcp 服务端的问题,vert.x 做 tcp 服务端要考虑哪些关键配置?除了考虑 tcp 协议本身导致的粘包拆包问题,还需要考虑或顾忌哪些配置设置?对于这方面,有资料或文档说明么?
    starcraft
        42
    starcraft  
       2020-05-21 11:43:01 +08:00
    这个帖子是迄今为止,在 v2 上看到关于 vertx webflux 最靠谱的了。
    itwarcraft88
        43
    itwarcraft88  
       2020-05-21 11:53:51 +08:00
    公司的新项目,打算上 springboot 2.3, 正好 release 了,使用 java+kotlin 混编,后台系统由另一个同事负责使用 springboot 的 web+mybatis,我搞移动端的 API,打算 kotlin+webflux+jdbc(感觉暂时用不到 r2dbc,性能要求不高),所以打算使用 mybatis,保持和另一个同事共享一部分代码,算是折腾尝试一下。如果觉得爽的话,再把老项目进行升级。
    yizmaoaa
        44
    yizmaoaa  
       2020-05-21 11:59:24 +08:00
    @tctc4869 其实我本身并没有开发过 TCP 服务端的问题。。。没有啥其他配置,使用 Vert.x 的唯一问题就是不要阻塞 EventLoop 。其他都一样。。。
    sagaxu
        45
    sagaxu  
       2020-05-21 12:03:38 +08:00 via Android
    @hantsy 同步方式很好描述的逻辑,异步就未必直观了,比如

    for (i=0,n=0; i<10; i++) {
    n = test(n, i);
    if (n == 0) contine;
    if (n == 1) n = test2(n, i);
    if (n == 3) break;
    n = test3(n, i);
    }

    每个 test 都是调用的第三方服务,转化成异步写法比较晦涩,这还只是简单的例子,实际 context 上的局部变量有很多个,回调和 promise 写法,需要自己维护这个 context,协程是系统帮你维护。协程只是增加一个选择,并不妨碍适合 rx 的地方继续 rx 。
    sagaxu
        46
    sagaxu  
       2020-05-21 12:09:28 +08:00 via Android
    @tctc4869 自己实现 TCP 服务,不需要考虑“黏包”这种细节,交给 RecordParser 去解析,只要设计协议的时候别搞出 parser 不方便解析的格式。
    hantsy
        47
    hantsy  
       2020-05-21 12:13:16 +08:00
    @itwarcraft88 这是我看到最奇葩的技术选型。WebFlux 用的 Reactor (也支持 Rxjava ) API,Jdbc/Mybatis 完全是遗留 老的一套 API (完全 Blocking ),你天天花时间在 Blocking 和 None Blocking 之间转 API ?

    如果仅仅是需要异步,不使用 Reactive Streams API,从上到下使用传统的 Java 8 CompletableFuture 就可以了。https://github.com/hantsy/spring-reactive-sample/tree/master/java8/src/main/java/com/example/demo
    qinfensky
        48
    qinfensky  
       2020-05-21 12:25:07 +08:00
    上 Vert.x
    tctc4869
        49
    tctc4869  
    OP
       2020-05-21 12:34:40 +08:00
    @sagaxu 我才知道有 RecordParser 这个东西,有机会去试试,不过我目前已经自己解决的粘包拆包问题,借助 connectHandler 内定义字段,然后配合自定义数据格式解决粘包拆包问题的。

    不过我还有辽宁一个问题,如果要用 vert.x 做 tcp 服务器,要注意什么关键的地方么?比如 NetServer 的配置设置,有哪些关键的地方么?
    jin7
        50
    jin7  
       2020-05-21 12:53:36 +08:00
    都不选 不折腾
    hantsy
        51
    hantsy  
       2020-05-21 13:30:15 +08:00
    Vertx 官方有一本系统介绍开发的书,https://vertx.io/docs/guide-for-java-devs/guide-for-java-devs.pdf

    Redhat 也出过一个本 Building Reactive Micorservices in Java,介绍 Vertx 为主

    https://developers.redhat.com/promotions/building-reactive-microservices-in-java/
    itwarcraft88
        52
    itwarcraft88  
       2020-05-21 13:42:53 +08:00
    @hantsy 看我的前提条件,本来就是学习实验性质的,我研究了一段时间的 vertx,最终在新项目上不使用原因也是因为使用 vertx 就要放下历史包袱,这个我们现在是做不到的,包括后台管理系统要使用旧的代码,传统的 mvc 进行开发,为了节省一些代码量,结合实际情况,同时熟悉下新技术(这个项目生命周期最多就是 1-2 年吧,不必长期维护那种)。
    itwarcraft88
        53
    itwarcraft88  
       2020-05-21 13:52:55 +08:00
    @hantsy 因为是刚开始尝试,我也知道很奇葩,就是图个学习和乐子,先熟悉一点相关的东西,如果写的难受了,或者项目再催的话,我可能随时再改回 springmvc 了。
    hantsy
        54
    hantsy  
       2020-05-21 14:01:30 +08:00
    @itwarcraft88 Spring 5 除了加入 WebFlux ( ReactiveStreams 标准支持),另外也是加入全新的 RouterFunction (区别于已经有的 Controller, 一种全新的开发模型)。不过这个已经 Port 到 Spring WebMvc 中,API 与 Reactive 版本类似,完全是使用传统 API,无 Reactor 那样的流式处理。

    https://github.com/hantsy/spring-webmvc-functional-sample
    tctc4869
        55
    tctc4869  
    OP
       2020-05-21 15:31:09 +08:00
    @yizmaoaa

    大佬,问一下,vert.x web 演示代码里,有一个 blockingHandler——阻塞处理,使用 vuert.x 的这个阻塞处理+传统的 jdbc 组合在性能上和使用 spring mvc+传统 jdbc 的组合是差不多的么?
    yizmaoaa
        56
    yizmaoaa  
       2020-05-21 15:47:57 +08:00
    @tctc4869 阻塞处理的测试结果可以参考 WebFlux 的。应该和 WebFlux+JDBC 在同一水准线上。我估摸着吞吐量也会比传统 SpringMVC+JDBC 高出 1-2 倍。但是我没实际测过
    twogoods
        57
    twogoods  
       2020-05-21 16:36:05 +08:00
    最近在适配 webflux,api 熟悉之后这种流式操作还是很爽,不过 debug 、异常处理确实成本上升,而且 java 里没协程,复杂点的逻辑 callback 确实不好处理。之所以适配 webflux 还是看他是 spring 社区的,springboot 项目改造肯定还是 webflux 方便,毕竟全家桶;不过还是要看其他组件如 db 等的 reactive 适配情况了。很早前做过一个类 mybatis 的异步 mysql 访问工具 https://github.com/twogoods/AsyncDao,不过使用的 mysql 异步驱动现在已经不维护了,感觉现在 mysql 的异步驱动真的很少啊,我看 vertx 新出了一个不过是 preview 版本
    epson3333
        58
    epson3333  
       2020-05-21 16:36:52 +08:00
    @lhx2008 那同样是异步编程,用 go 就没这种问题吗
    chihiro2014
        59
    chihiro2014  
       2020-05-21 16:52:38 +08:00
    @twogoods webflux 个人感觉还行。Vertx 反倒生态小。出了问题难说。目前 oracle 正在推出官方的 mysql 和 oracle 的 r2dbc 的
    lhx2008
        60
    lhx2008  
       2020-05-21 17:03:07 +08:00 via Android
    @epson3333 go 是同步编程,做到代码阻塞(协程阻塞)操作的时候线程不阻塞,这样就不用开很多线程就可以一直处理,效率类似异步
    godoway
        61
    godoway  
       2020-05-21 17:18:20 +08:00 via Android
    @tctc4869 你是指 route 的 block handler 么
    一般来说不会用到这个,这个是到 worker 线程池里面拿一条线程来处理请求了。
    正常来说请求的处理应该也是尽量使用 event loop 来处理。
    在使用传统 jdbc 场合按官方的设计是使用 worker 线程处理请求数据库然后再传递到 event loop 线程。
    其实就是熟悉的 netty 里的 event loop 和业务线程池组合的玩法。
    PS4Platinum
        62
    PS4Platinum  
       2020-05-21 17:35:30 +08:00
    没用过的话 都是坑
    tctc4869
        63
    tctc4869  
    OP
       2020-05-21 17:43:17 +08:00
    @godoway 使用传统 jdbc 场合,有官方的设计配置策略推荐?这个是在官方文档里哪里,我没找到。能给个链接么?
    louislivi
        64
    louislivi  
       2020-05-21 17:44:38 +08:00
    先普及 java 9-11 吧 [手动狗头]
    godoway
        65
    godoway  
       2020-05-21 18:13:40 +08:00 via Android
    @tctc4869 官方有一个 JDBC client,
    另外自己接 mybatis 之类的需要 worker verticle
    然后通过 eventbus 通讯(这部分可以用 codegen 生成 service proxy 代码)
    godoway
        66
    godoway  
       2020-05-21 18:19:23 +08:00 via Android
    @tctc4869 忘了提还有一个 vertx.executeBlock
    tctc4869
        67
    tctc4869  
    OP
       2020-05-21 20:17:48 +08:00
    @godoway
    找到了,你指的是在官方 vert.x core 核心文档下的 Running blocking code 那一节内容的演示的代码?我连 postgresql,用传统的 jdbc 驱动 jar 包,同时为了开发方便使用 orm 框架,如果是在 vert.x core 体系下,官方建议是用 Running blocking code 那一节的那里演示的代码吧?

    不过你为什么会提 jdbc-client ?这个是 vert.x 出的把,如果用这个,那传统的 jdbc 驱动配合 orm 框架(不一定指 mybatis ),就 用不了吧。难道 jdbc-client 配合 worker verticle 和 vertx.executeBlock 是更好?
    hantsy
        68
    hantsy  
       2020-05-21 20:28:50 +08:00
    @twogoods
    @chihiro2014
    MySQL 的 r2dbc 驱动有好两家了,https://r2dbc.io/

    不过记得以前 Oracle Blog 中提到要重新定义一套 Jdbc 标准,不道道进度如何。

    目前 R2dbc 规范是 Spring 自己的一套体系,API 太依赖 Reactor 。Redhat 明显对它不感冒,Vertx,Quarkus 都是了 SmallyRye Munity 实现支持 Reactive Streams 标准,当然也可以与现有的 Reactor,Rxjava 互通。
    hantsy
        69
    hantsy  
       2020-05-21 20:34:22 +08:00
    找到一篇 Oracle blog: Asynchronous Database Access API (ADBA)
    https://blogs.oracle.com/java/jdbc-next:-a-new-asynchronous-api-for-connecting-to-a-database
    hantsy
        70
    hantsy  
       2020-05-21 20:39:18 +08:00
    目前 RDBMS 只有 R2dbc 是重新设计,很多其它的什么异步 Jdbc 操作都是用异步 API 包装 Jdbc 而已,没有彻底从驱动层解决问题。
    chihiro2014
        71
    chihiro2014  
       2020-05-21 21:24:50 +08:00
    @hantsy ADBA 已经 gg 了。Oracle 正在重新弄 r2dbc 相关的东西
    godoway
        72
    godoway  
       2020-05-22 00:14:56 +08:00
    @tctc4869 我想说 jdbc-client 的实现就是在 worker 线程池跑查询,获取结果后在你调用的线程(eventloop)回调。
    而 executeBlocking(Handler<Promise<T>> blockingCodeHandler, Handler<AsyncResult<T>> resultHandler)
    这个方法干的就是这个,blockinghandler 在 worker 线程上执行,result 在你当前调用线程执行。
    worker verticle 的话则是启用一个绑定了 worker 线程的 verticle,也就是里面的所有操作占用的都是 worker 线程而非 eventloop 。
    所以使用传统 jdbc 的场合有两条路给你封装,一个是利用 executeBlocking,一个是封装成 worker verticle 。
    PS. postgresql 建议可以考虑使用 vertx-pg-client,这个是异步的,不过还不是很完善就是了。
    tctc4869
        73
    tctc4869  
    OP
       2020-05-22 08:19:32 +08:00
    @godoway 对了,大佬,我还想问一下,你对 vert.x core 做 tcp 服务端有什么了解么?如果不了解,可以无视后面的话。

    用 vert.x 做 tcp 服务端,要注意什么关键的地方么?比如 NetServer 的配置设置,有哪些关键的地方么?而在 vert tcp 的 handler 里,运行同步代码,同样也得用 executeBlocking 和封装成 worker verticle 。除了这个,还有哪些要注意的么?
    ppgs8903
        74
    ppgs8903  
       2020-05-22 08:59:26 +08:00
    当然都不选,选 SPRING BOOT 的 SPRINNG MVC 模板
    godoway
        75
    godoway  
       2020-05-22 09:10:09 +08:00 via Android
    @tctc4869 虽然不太了解,不过核心思路一样的。就是非阻塞且耗时短的都可以交给 eventloop,阻塞或耗时长的都要交给 worker 。
    例如你有一个计算很久的代码,如果交给 event loop 那么这个 event loop 就没法去处理其他了,所以要用 worker 。
    其实 tcp 部分把他当成 netty 就是了
    sagaxu
        76
    sagaxu  
       2020-05-22 09:32:06 +08:00 via Android
    @tctc4869 使用 vertx 得搞明白 vertcle 和 context,唯一需要注意的点是 don't block the eventloop 。
    micean
        77
    micean  
       2020-05-22 10:07:24 +08:00
    用了 vertx4 年了,vertx 最大的优势在于学习成本低……spring 的代码我是真的不想看。
    但是 vertx 的组件真的很简易,比如说最新 4.0 的日志链路追踪,他只实现了 IO 时的接口,阻塞、非阻塞线程之间却没有,真的恼火。又比如在集群模式中,某种情况下节点失效时,没有处理发送失败的异常的接口……
    所以想用 vertx 一定要自己封装……
    hantsy
        78
    hantsy  
       2020-05-22 10:43:14 +08:00
    @chihiro2014 Oracle 首先实现了自己的一套 reactive jdbc 扩展(基于 Java 9 Flow ),然后再估计用个 Adaper 支持 R2dbc, https://groups.google.com/forum/#!msg/r2dbc/A9s8rN7EOPA/Db71lq2qAQAJ

    目前 Oracle 的 Helidon 项目中的 Db Client 对 RDBMS 的异步操作也是封装了 JDBC 的 API,https://github.com/hantsy/helidon-sample/blob/master/se-dbclient/src/main/java/demo/PostRepository.java 驱动依赖还是 JDBC 。
    ourslay
        79
    ourslay  
       2020-05-22 13:35:23 +08:00 via iPhone
    最近的项目选的 Spring WebFlux + R2DBC 。
    有时间折腾那么 quarkus 也是个不错的选择
    tctc4869
        80
    tctc4869  
    OP
       2020-05-22 18:44:44 +08:00
    @sagaxu
    @godoway
    @yizmaoaa

    vert.x 3.9 和 4.0 支持 jdk14 和 openjdk 1.4 么?
    tctc4869
        81
    tctc4869  
    OP
       2020-05-30 20:58:23 +08:00
    @micean
    @hantsy
    @sagaxu
    @godoway

    我想问一下,为什么我在自定义的 tcp 服务端 NetServer 实例的 handler 方法里用 executeBlocking 执行阻塞代码
    Vertx.vertx().executeBlocking(promise -> {
    // Call some blocking API that takes a significant amount of time to return


    try {
    throw new Exception("123");
    }catch (Exception e) {
    // TODO: handle exception
    }

    promise.complete(result);
    },false, res -> {

    });


    会提示这个该警告:You're already on a Vert.x context, are you sure you want to create a new Vertx instance?

    还不抛出异常,这是怎么回事,还缺什么设置配置吗?我在 main 函数里直接测试如上代码,没有该出现警告,异常还是会抛出。奇怪了,有人知道是怎么会是么
    micean
        82
    micean  
       2020-05-30 21:23:48 +08:00
    @tctc4869

    每个 verticle 都已经声明了 vertx 的成员变量,直接用 vertx.executeBlocking 即可,Vertx.vertx()会生成一个新的 vertx 实例。
    特殊情况也可以用 Vertx.currentContext().owner()来获取当前的 vertx 实例。
    ychost
        83
    ychost  
       2020-06-26 13:17:09 +08:00
    最近准备试试 vert.x 这货好像还支持 js
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   我们的愿景   ·   实用小工具   ·   3045 人在线   最高记录 6543   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 81ms · UTC 14:54 · PVG 22:54 · LAX 07:54 · JFK 10:54
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.