您的 Java 8 响应式应用准备就绪,Reactor 3.0 GA 现已发布!

版本发布 | Stephane Maldini | 2016年9月27日 | ...

经过一年多的开发多个里程碑以及基于大量反馈的微调,我很高兴地宣布 Reactor 3 正式发布。您可以在 Maven Central 上找到 Reactor Core 3.0.2.RELEASE。

Join the chat at https://gitter.im/reactor/reactor Reactor Core

什么是 Reactor 3?

Reactor 3 为基于 Java 8 的应用程序提供了一个强大而高效的响应式编程模型。该模型建立在Reactor 2RxJava 1的经验之上,并引入了一种流畅的方式来组合异步、支持背压的事件处理。 Spring Framework 5 使用 Reactor 3来构建并最终公开一个完整的响应式故事

其设计依赖于一个可扩展的执行模型,该模型有利于事件处理的本地化。通常,Reactor 只有在明确要求时才会在事件流阶段之间切换线程。例如,内存操作(如列表访问或有效负载转换)通常不需要线程边界。如果操作生产者或接收者可能需要时间,则用户应使用Flux#publishOn / Mono#publishOnFlux#subscribeOn / Mono#subscribeOn操作其流,并选择一个Scheduler来运行。或者,如果用户正在组合许多Publisher的结果(如使用mergeconcat),Reactor将以线程安全的方式隐式处理各种潜在的线程边界。实际上,至少有一个生产线程和一个接收线程可能会遍历由Publisher托管的流阶段。

所有这些都是根据Reactive Streams规范中定义的行为实现的。Reactor致力于使规范成为库编写者或Spring开发人员的商品,并提供预制操作符,您可以在流和/或异步场景中应用这些操作符。

Mono 和 Flux

流定义是 Reactor 根据流入已定义流的数据量,称为FluxMono的操作链。这些类型在每个阶段都实现了 Reactive Streams Publisher,并且可以通用地传递。那么为什么会有两种响应式类型呢?因为基数对 Reactor 来说很重要。Flux将观察 0 到 N 个项目,并最终成功或不成功地终止。Mono将观察 0 或 1 个项目,其中Mono<Void>暗示最多 0 个项目。

让我们看看以下阻塞 API

interface BlockingUserRepository {
     User get(String id);
     List<User> findAll();
     void save(User data) throws RepositoryException;
     List<User> findAllByUsernameLike(String s);
}

使用普通的 Reactive Streams Publisher,我们将得到以下契约

interface ReactiveUserRepository {
     Publisher<User> get(String id);
     Publisher<User> findAll();
     Publisher<Void> save(Publisher<? extends User> source);
     Publisher<User> findAllByUsernameLike(String s);
}

但是使用 Reactor,我们可以保留预期基数的语义证据

interface ReactorUserRepository {
     Mono<User> get(String id);
     Flux<User> findAll();
     Mono<Void> save(Publisher<? extends User> source);
     Flux<User> findAllByUsernameLike(String s);
}

由于MonoFlux都实现了Publisher,因此我们可以轻松地将它们的任何引用作为Reactive 数据源传递,同时使用Mono<Void>流畅的 API 返回显式语义

// ReactorUserRepository userRepository;

userRepository.save(Mono.fromCallable(() -> new User("thomas")))
              .doOnSuccess(res -> success())
              .subscribe();

userRepository.save(Flux.just(new User("bob"), new User("robert")))
              .doOnSuccess(res -> success())
              .subscribe();

请记住,FluxMono适用于可能需要时间的数据库生产者。为了管理重入和线程安全性,操作符有时必须在执行的流中添加一些开销。尽管如此,效率仍然是核心关注点,并且我们定期从我们的引擎贡献者 David Karnok 那里获得报告。Reactor 3 目前是 JVM 上最高效的响应式库之一。除了这些直接相关的基准测试之外,我们现在也受益于 RxJava 2 社区的反馈,因为它在概念上源于同一个工匠和熔炉:Reactive Streams Commons

接下来是什么?

我们将在未来几周内致力于 3.0.3 版本,并与 Spring 5、CloudFoundry 和 Reactive Streams Commons 的最新研究保持同步。

我们的优先事项将包括:

  • 新的测试支持:Reactor 3 计划包含测试支持,但是最初的反馈提出了一些用户体验问题。我们现在正在努力提供这部分缺失的功能。同时,用户可以轻松地复制我们测试中的隔离TestSubscriber以满足其需求。

  • 指南:虽然 Reactor 3 越来越受欢迎,但我们仍在与内部或外部的许多人互动,包括拥有 Rx 知识的高级用户以及由Sebastien Deleuze贡献的快速教程。您将在本文末尾找到更多资源,但我们已经开始建立一些我们认为具体、有价值的端到端场景,这些场景将有助于塑造官方的参考 Reactor 指南。

Reactor IPC

IPC 代表进程间通信,Reactor IPC 是一项正在进行的计划,旨在回答“如何在 Reactive Streams 方式下摆脱 JVM”的问题。我们正在使用Reactor KafkaReactor AeronReactor Netty开发一组初始实现。事实上,现在正在进行许多关于契约重新设计以及 Reactor Kafka/Netty 工作的事情,这些工作支持了一些新的 Spring 响应式故事。IPC 伞的意图不是创建新的 Web 或消息框架,而是响应式驱动程序应用程序或类似的库可以构建在其之上。它们将给定的运行时输入/输出转换为FluxMonoSubscriber,将响应式背压传播到 IO 访问层。预计未来几个月将会有大量关于这些计划的消息。

致谢

让我们花点时间感谢参与此版本发布的人员。David Karnok是新 Reactor 引擎的主要架构师,并领导Reactive Streams Commons的研究工作。Spring、Eclipse STS 和 CloudFoundry Client 团队在贡献设计改进和反馈方面发挥了重要作用。除了 Pivotal 之外,MuleSoft 也对最新的开发工作提供了巨大的帮助和积极支持。

RxJava 1将主流 Reactive 带到了 JVM,其完整的函数式 Rx 代数已成为我们遵循的行业标准。它启发了我们使用Reactive Streams实施的具有变革意义的规范,并汇集了 Netflix、Oracle、Pivotal、Typesafe、Red Hat 等 JVM 关键参与者。

资源

敬请期待更多响应式故事!Pivotal 的 Reactor 之旅才刚刚开始,经过过去几年的努力和研究,我们很高兴能提供一种全新的体验。我们的价值主张与 Spring 开源项目直接相关,我们拥有一个独特的机会,能够在整个 Spring 产品组合中以端到端的方式交付响应式管道。

最后,Spring 和 Reactor 对我们社区、对您,表示感谢,感谢您的大力支持、鼓励和反馈。多年来我们建立的反馈循环不仅仅是一种良好的务实合作,它也是我们所有人逐步改变行业所需的。

获取 Spring 时事通讯

关注 Spring 时事通讯

订阅

抢先一步

VMware 提供培训和认证,助您加速进步。

了解更多

获取支持

Tanzu Spring 在一个简单的订阅中提供 OpenJDK™、Spring 和 Apache Tomcat® 的支持和二进制文件。

了解更多

即将举行的活动

查看 Spring 社区中所有即将举行的活动。

查看全部