0

我对响应式编程非常陌生,目前正在研究使用 spring mvc 的微服务和用于数据库连接的 Spring Data MongoDb。

当我浏览 Spring Data mongo db 文档时,支持响应式存储库、响应式模板 api 等。

那么,如果我选择使用具有阻塞性质的反应式模板和存储库,会有什么缺点吗?

Ex.    
reactiveMongoTemplate.add(entity).block()
reactiveMongoTemplate.update(id, entity).block()

使用上述调用与使用阻塞存储库和模板 api 本身有什么显着区别吗?

4

2 回答 2

4

答案取决于您使用的堆栈:Spring WebFlux 或 Spring Web MVC。

Spring WebFlux的情况下,选择是显而易见的:您必须使用 ReactiveMongoTemplate并且永远不要调用 block它,而是在从模板中获取 Mono/Flux 时返回它。

Spring Web MVC的情况下,您可以自由使用常规阻塞 MongoTemplate 和 ReactiveMongoTemplate with block. 虽然,在大多数情况下,为了简单和性能,您应该使用旧的 MongoTemplate 。与阻塞 MongoTemplate 相比,ReactiveMongoTemplate 有一些开销,因为反应类型 Mono/Flux 给内存带来了一些额外的压力。

我可以想象一个用例,即使在 Spring MVC 中 ReactiveMongoTemplate 也可以提供一些优势:在一个 HTTP 请求期间,您必须同时执行多个 Mono 操作。如果您使用阻塞 MongoTemplate,那么您需要设置一个线程池并在那里委派查询执行。但是,使用 ReactiveMongoTemplate,您可以使用 Mono 和 Flux 的许多运算符来完成此任务,而无需担心线程、线程池和缩放问题。

于 2020-08-18T15:26:22.047 回答
1

在传统编程中,您通常拥有正在运行的线程,而在反应式编程中,情况并非如此。这个“底层执行单元”(如果您愿意,可以使用 cpu 资源消费者)不是您的,而是当前恰好执行您的任务的“全局”事物,但很快就可以切换到做其他事情。

所以当你阻塞时,你对这个“全局执行单元”说“嘿,停止做其他事情,等我”。在传统方法中,这还不错,因为您有一个与当前请求相关联的线程,其他请求(或如果您的系统不是基于 Web 的流)应该与从相当大的线程池中获取的其他线程一起执行。然而,在反应式系统中,情况并非如此,因为您试图使用少量这些“全局执行单元”。

好的,所以如果你阻塞,整个地方的事件将停止发射并开始缓冲。这可能会导致整个系统变得无法使用。

于 2020-08-18T05:17:25.437 回答