使用 Reactor 2.0 在 Spring 4 上执行多线程
Posted
技术标签:
【中文标题】使用 Reactor 2.0 在 Spring 4 上执行多线程【英文标题】:Multithread execution on Spring 4 using Reactor 2.0 【发布时间】:2015-08-03 22:25:45 【问题描述】:我正在尝试将Reactor 2x 集成到现有的Spring 4
应用程序中,以在执行REST
请求期间提高性能,其中resources
可以相互独立地获取,有点像我们的map-reduce将一个作业并行化为多个线程,然后将它们加入缓冲区。
到目前为止,我们有这个示例在非弹簧环境中工作:
//Ordered resources to apply transformations.
List<Map<String, Object>> result;
result = Streams.from(resources)
.flatMap(m -> Streams.just(m) .dispatchOn(Environment.cachedDispatcher())
.map(resourceToMapFunction::apply))
.buffer().next().await(5, TimeUnit.SECONDS);
在上面的示例中,我们使用resourceToMapFunction
应用转换,然后使用buffer()
方法连接,创建Promise
以等待结果并返回result
。
我的第一个问题,这是应该使用 Reactor 的方式吗?我知道转换是正确应用的,但也许,我是Reactor
的新手,没有使用正确的方法。
我的第二个问题,没什么大不了的,但是Reactor
项目中是否有任何东西可以按照resources
输入中提供的相同顺序返回?由于这是在多个线程中执行的,所以我很确定答案不是,而且就像我说的那样,我的担心更少,但无论如何都想问。
最后一个问题,当我将此代码引入我的 Spring
项目时,转换失败,因为应用底层转换的 Bean
依赖项不在执行线程中,这是我可以使用 Spring Reactor 版本轻松完成的事情?如果是这样,是否有任何链接或文档说明如何操作?
非常感谢!
何塞·路易斯
【问题讨论】:
【参考方案1】:您应该使用 Reactor 的 API。因此,与其创建 Java Stream
,不如创建 Reactor Flux
。然后你应该使用Flux
的flatMap
函数来获取一些资源。如果您希望资源与请求的顺序相同,您可以使用flatMapSequential
。
所以代码看起来像:
Flux<Map<String,Object>> result = Flux.fromIterable(resources)
.flatMapSequential(resourceToMapFunction::apply)
.take(Duration.ofSeconds(5));
然后你有一个 Reactor 流,你可以对该流应用更多操作。如果您想要简单的列表,则必须使用运算符collectList
进行阻止。如果您想控制执行给定函数的线程,那么您必须熟悉Scheduler
。
【讨论】:
【参考方案2】:React 库会有很大帮助。 Spring 5 支持响应式编程(和异步 servlet),而不是 Spring 4。
Spring 4 仍然支持一些基本的异步特性。对于您的情况,它必须足够。下面是一个基于@EnableAsync
和CompletableFuture
的小例子:
https://dzone.com/articles/multi-threading-in-spring-boot-using-completablefu
【讨论】:
以上是关于使用 Reactor 2.0 在 Spring 4 上执行多线程的主要内容,如果未能解决你的问题,请参考以下文章
使用 reactor netty 为 spring-webflux WebClient 配置 HostnameVerifier
Spring & Reactor:使用来自 repo 的 Flux 订阅两个参数的二进制函数
(14)Reactor调度器与线程模型——响应式Spring的道法术器
(17)Reactor的调试——响应式Spring的道法术器