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

标签 spring-data-mongodb spring-webflux project-reactor reactor-netty

在我有一个带有 Reactor Netty 的 Spring Webflux 微服务的用例中,我有以下依赖项:

  • 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.projectreactor.reactor-spring (1.0.1.RELEASE)

  • 对于一个非常特殊的情况,我需要从我的 Mongo 数据库中检索一些信息,并将其处理为与我的响应式(Reactive) WebClient 一起发送的查询参数。 .如 WebClient也不是 UriComponentsBuilder接受发布者(Mono/Flux)我使用了 #block()调用以接收结果。

    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

    我的代码片段:

    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);
    }
    

    这适用于 spring-boot版本 2.0.0.RELEASE,但由于升级到版本 2.0.1.RELEASE,因此从 reactor-core 升级到版本 0.7.6.RELEASE 它不再被允许。

    我看到的唯一真正的解决方案是包含一个块(非 react 性)存储库/mongo 客户端,但我不确定是否鼓励这样做。有什么建议?

    最佳答案

    WebClient不接受 Publisher键入其请求 URL,但没有什么可以阻止您执行以下操作:

    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;         
    }
    

    如果有的话,这个新的 react 器核心检查使您免于在 WebFlux 处理程序中间使用此阻塞调用使整个应用程序崩溃。

    关于spring-data-mongodb - 如何在 Spring Webflux/Reactor Netty Web 应用程序中执行阻塞调用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49746372/

    相关文章:

    mongodb - Spring Data - MongoDB - 使用 GroupOperation 在聚合管道中进行文本搜索和总分

    java - 如何通过内部映射中的参数查找 mongo 文档(最好使用 Spring MongoTemplate)

    spring-boot - NoSuchMethodException QueryDSL 与 Spring Boot 和 Spring Data Mongo

    java - 带有 JPA 和 R2DBC 的 Spring Boot 2.4 混合项目无法启动

    java - Spring react 器: What's the corresponding class to Optional<T>?

    java - Spring MongoDB 手册引用

    java - 你如何在 Spring Cloud Gateway (Webflux) POST 过滤器中读取响应主体

    rx-java - 项目reactor中是否有相当于RxJava Completable的东西?

    Java Reactor Flux/Mono,在元素发出之前或之后什么时候触发 doOnNext?

    java - 无法在本地主机 :8080/h2-console when using webflux 访问 H2 数据库