简体   繁体   English

如何在 Spring Webflux / Reactor Netty Web 应用程序中执行阻塞调用

[英]How to execute blocking calls within a Spring Webflux / Reactor Netty web application

In my use case where I have a Spring Webflux microservice with Reactor Netty, I have the following dependencies:在我有一个带有 Reactor Netty 的 Spring Webflux 微服务的用例中,我有以下依赖项:

  • org.springframework.boot.spring-boot-starter-webflux (2.0.1.RELEASE) org.springframework.boot.spring-boot-starter-webflux (2.0.1.RELEASE)
  • org.springframework.boot.spring-boot-starter-data-mongodb-reactive (2.0.1.RELEASE) org.springframework.boot.spring-boot-starter-data-mongodb-reactive (2.0.1.RELEASE)
  • org.projectreactor.reactor-spring (1.0.1.RELEASE) org.projectreactor.reactor-spring (1.0.1.RELEASE)

For a very specific case I need to retrieve some information from my Mongo database, and process this into query parameters send with my reactive WebClient .对于一个非常特殊的情况,我需要从我的 Mongo 数据库中检索一些信息,并将其处理为通过我的反应式WebClient发送的查询参数。 As the WebClient nor the UriComponentsBuilder accepts a Publisher (Mono / Flux) I used a #block() call to receive the results.由于WebClientUriComponentsBuilder接受发布者(Mono / Flux),我使用#block()调用来接收结果。

Since reactor-core (version 0.7.6.RELEASE) which has been included in the latest spring-boot-dependencies (version 2.0.1.RELEASE) it is not possible anymore to use: block()/blockFirst()/blockLast() are blocking, which is not supported in thread xxx , see -> https://github.com/reactor/reactor-netty/issues/312由于reactor-core (版本 0.7.6.RELEASE)已包含在最新的spring-boot-dependencies (版本 2.0.1.RELEASE)中,因此无法再使用: block()/blockFirst()/blockLast() are blocking, which is not supported in thread xxx ,请参阅 -> https://github.com/reactor/reactor-netty/issues/312

My code snippet:我的代码片段:

public Mono<FooBar> getFooBar(Foo foo) {
    MultiValueMap<String, String> parameters = new LinkedMultiValueMap<>();
    parameters.add("size", foo.getSize());
    parameters.addAll("bars", barReactiveCrudRepository.findAllByIdentifierIn(foo.getBarIdentifiers()) // This obviously returns a Flux
        .map(Bar::toString)
        .collectList()
        .block());

    String url = UriComponentsBuilder.fromHttpUrl("https://base-url/")
        .port(8081)
        .path("/foo-bar")
        .queryParams(parameters)
        .build()
        .toString();

    return webClient.get()
        .uri(url)
        .retrieve()
        .bodyToMono(FooBar.class);
}

This worked with spring-boot version 2.0.0.RELEASE, but since the upgrade to version 2.0.1.RELEASE and hence the upgrade from reactor-core to version 0.7.6.RELEASE it is not allowed anymore.这适用于spring-boot版本 2.0.0.RELEASE,但由于升级到版本 2.0.1.RELEASE 并因此从reactor-core升级到版本 0.7.6.RELEASE 它不再被允许。

The only real solution I see is to include a block (non-reactive) repository / mongo client as well, but I'm not sure if that is encouraged.我看到的唯一真正的解决方案是包含一个块(非反应性)存储库/mongo 客户端,但我不确定是否鼓励这样做。 Any suggestions?有什么建议吗?

The WebClient does not accept a Publisher type for its request URL, but nothing prevents you from doing the following: WebClient不接受其请求 URL 的Publisher类型,但没有什么可以阻止您执行以下操作:

public Mono<FooBar> getFooBar(Foo foo) {

    Mono<List<String>> bars = barReactiveCrudRepository
        .findAllByIdentifierIn(foo.getBarIdentifiers())
        .map(Bar::toString)
        .collectList();

    Mono<FooBar> foobar = bars.flatMap(b -> {

        MultiValueMap<String, String> parameters = new LinkedMultiValueMap<>();
        parameters.add("size", foo.getSize());
        parameters.addAll("bars", b);

        String url = UriComponentsBuilder.fromHttpUrl("https://base-url/")
            .port(8081)
            .path("/foo-bar")
            .queryParams(parameters)
            .build()
            .toString();

        return webClient.get()
            .uri(url)
            .retrieve()
            .bodyToMono(FooBar.class);
    });
    return foobar;         
}

If anything, this new reactor-core inspection saved you from crashing your whole application with this blocking call in the middle of a WebFlux handler.如果有的话,这个新的反应器核心检查使您免于在 WebFlux 处理程序中间使用此阻塞调用使整个应用程序崩溃。

暂无
暂无

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

相关问题 Spring Boot WebFlux Reactive MongoDB:如何在每个请求上切换数据库? - Spring Boot WebFlux Reactive MongoDB: how to switch the database on each request? Spring Webflux WebExceptionHandler 不会被 OptimisticLockingFailure 触发 - Spring Webflux WebExceptionHandler not being Triggered by OptimisticLockingFailure 有没有办法在 spring webflux 和 spring data reactive 中实现分页 - Is there any way to implement pagination in spring webflux and spring data reactive Spring WebFlux:在Spring Data MongoDB反应库中发出null值的异常? - Spring WebFlux: Emit exception upon null value in Spring Data MongoDB reactive repositories? 在响应式(Webflux)应用程序中正确使用可变的mongodb实体 - Correct use of mutable mongodb entities in reactive (webflux) application 如何使用mongoDB和spring数据在嵌入式文档中创建id - how to create an id within the embedded document using mongoDB and spring data MongoDB的Spring数据中的非阻塞查询? - Non-blocking Queries in Spring Data for MongoDB? 使用带有阻塞方法的反应性 spring 数据 (mongdb) 的不利/性能影响 - Downside/Performace Impact in using reactive spring data (mongdb) with blocking methods 如何加载mongo存储库以弹出测试应用程序上下文? - How to load mongo repository to spring test application context? 如何在Spring Boot应用程序中以JSONObject的形式访问MongoDB文档 - How to access MongoDB document as JSONObject in spring boot application
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM