抢先一步
VMware 提供培训和认证,助您加速进步。
了解更多经过一年多的开发,多个里程碑以及基于大量反馈的微调,我很高兴地宣布 Reactor 3 正式发布。您可以在 Maven Central 上找到 Reactor Core 3.0.2.RELEASE。
Reactor 3 为基于 Java 8 的应用程序提供了一个强大而高效的响应式编程模型。该模型建立在Reactor 2和RxJava 1的经验之上,并引入了一种流畅的方式来组合异步、支持背压的事件处理。 Spring Framework 5 使用 Reactor 3来构建并最终公开一个完整的响应式故事。
其设计依赖于一个可扩展的执行模型,该模型有利于事件处理的本地化。通常,Reactor 只有在明确要求时才会在事件流阶段之间切换线程。例如,内存操作(如列表访问或有效负载转换)通常不需要线程边界。如果操作生产者或接收者可能需要时间,则用户应使用Flux#publishOn
/ Mono#publishOn
或Flux#subscribeOn
/ Mono#subscribeOn
操作其流,并选择一个Scheduler来运行。或者,如果用户正在组合许多Publisher
的结果(如使用merge或concat),Reactor将以线程安全的方式隐式处理各种潜在的线程边界。实际上,至少有一个生产线程和一个接收线程可能会遍历由Publisher
托管的流阶段。
所有这些都是根据Reactive Streams规范中定义的行为实现的。Reactor致力于使规范成为库编写者或Spring开发人员的商品,并提供预制操作符,您可以在流和/或异步场景中应用这些操作符。
流定义是 Reactor 根据流入已定义流的数据量,称为Flux或Mono的操作链。这些类型在每个阶段都实现了 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);
}
由于Mono
和Flux
都实现了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();
请记住,Flux
和Mono
适用于可能需要时间的数据库生产者。为了管理重入和线程安全性,操作符有时必须在执行的流中添加一些开销。尽管如此,效率仍然是核心关注点,并且我们定期从我们的引擎贡献者 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 指南。
IPC 代表进程间通信,Reactor IPC 是一项正在进行的计划,旨在回答“如何在 Reactive Streams 方式下摆脱 JVM”的问题。我们正在使用Reactor Kafka、Reactor Aeron和Reactor Netty开发一组初始实现。事实上,现在正在进行许多关于契约重新设计以及 Reactor Kafka/Netty 工作的事情,这些工作支持了一些新的 Spring 响应式故事。IPC 伞的意图不是创建新的 Web 或消息框架,而是响应式驱动程序应用程序或类似的库可以构建在其之上。它们将给定的运行时输入/输出转换为Flux
和Mono
或Subscriber
,将响应式背压传播到 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 对我们社区、对您,表示感谢,感谢您的大力支持、鼓励和反馈。多年来我们建立的反馈循环不仅仅是一种良好的务实合作,它也是我们所有人逐步改变行业所需的。