简体   繁体   English

使用一些阻塞操作构建 Spring 反应式 API 是否“可以”

[英]Is it "okay" to build a Spring Reactive API with some Blocking Operations

I'm just kind of getting started with Spring and I want to build a RESTful API for a project I'm working on.我只是开始使用 Spring,我想为我正在处理的项目构建一个 RESTful API。 My backend has a lot of HTTP calls to third-party services, I've decided that it would be prudent to implement a Reactive design and have the architecture be non-blocking.我的后端有很多对第三方服务的 HTTP 调用,我决定实施反应式设计并让架构是非阻塞的是谨慎的。 I'm using Retrofit and it has a callback-based async API which will work fine for me.我正在使用 Retrofit 并且它具有基于回调的异步 API 对我来说可以正常工作。 Here's the problem;这就是问题所在; I've already implemented my database and models using Hibernate and JPA, it's really mature and can handle everything from migrations to validations and everything in between, I like using JPA, but it's blocking and so doesn't fit neatly in my architecture design.我已经使用 Hibernate 和 JPA 实现了我的数据库和模型,它非常成熟,可以处理从迁移到验证以及介于两者之间的所有事情,我喜欢使用 Z9CE3D1BD8890F16A0C44809359507 Is it okay to have the reactive stack everywhere else and perhaps migrate the persistence stuff to a reactive model later when the tooling and frameworks are almost at par with JPA?当工具和框架几乎与 JPA 相当时,是否可以在其他任何地方使用响应式堆栈,并可能将持久性内容迁移到响应式 model? The main issue is creating the database schema at start-up, if there's a solution to that, I'd be glad to work with it.主要问题是在启动时创建数据库模式,如果有解决方案,我很乐意使用它。

blocking in any fully reactive webflux application is bad from a performance perspective.从性能的角度来看,在任何完全反应式的 webflux 应用程序中阻塞都是不好的。

Webflux starts with a very few number of threads, which means that if you block there is a high risk that your application will (under load) be susceptible to thread starvation, this because no new threads spawn in reactive applications, and your applications small thread pool will be blocked waiting for responses from your database. Webflux 从很少数量的线程开始,这意味着如果您阻塞,您的应用程序(在负载下)很容易受到线程饥饿的影响,这是因为在反应式应用程序中不会产生新线程,并且您的应用程序是小线程池将被阻止等待来自您的数据库的响应。

There is a workaround which is that you place all potential blocking calls instead on its own scheduler, using the subscribeOn operator.有一种解决方法是您使用subscribeOn运算符将所有潜在的阻塞调用放在它自己的调度程序上。 This is documented in the reactor documentation这记录在反应堆文档

Just remember by wrapping blocking calls, you will not get the benefits from reactive programming, like a smaller memory footprint, and potentially higher throughput.请记住,通过包装阻塞调用,您不会从反应式编程中获得好处,例如更小的 memory 占用空间和潜在的更高吞吐量。 But at least you will not suffer from thread starvation.但至少你不会遭受线程饥饿的痛苦。

Those calls will instead behave like "regular calls" to a "regular spring boot web server" since those calls will get assigned a single thread that will follow the call throughout execution.相反,这些调用的行为类似于对“常规 spring 启动 web 服务器”的“常规调用”,因为这些调用将被分配一个线程,该线程将在整个执行过程中跟随调用。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM