为什么webclient在这个webflux应用程序中被阻塞?

icnyk63a  于 2021-07-23  发布在  Java
关注(0)|答案(1)|浏览(402)

我正在开发一个webflux应用程序,它公开一个http端点,该端点进行webclient调用,然后修改webclient调用的响应主体,然后返回到客户端。当我启用blockhound时,我发现它正在阻塞,我正在试图找出原因。
下面是最简单的代码版本,我可以想出重新创建的行为。我还把一个工作项目放在这里:https://github.com/aztosca/web-client-test. 注入的webclient.builder是他们推荐使用的spring的预配置示例。
我假设blockhound抱怨是因为eventloop线程被阻塞了。我认为使用webclient可以防止这种情况的发生,并确保在适当的线程上发生任何阻塞,但是这里发生了一些我还不明白的事情(我是webflux的新手)。
有人能帮我理解为什么这是一个线程阻塞它不应该阻塞?并建议如何修复?
内蒂:4.1.58
Spring Boot:2.4.2
Spring:5.3.3

@SpringBootApplication
public class WebClientTestApplication {

    public static void main(String[] args) {
        BlockHound.install();
        SpringApplication.run(WebClientTestApplication.class, args);
    }

    static String endpoint  =  "http://postman-echo.com/get?name=value";

    @Bean
    public RouterFunction<ServerResponse> testWebClient(WebClient.Builder webClientBuilder) {

        WebClient webClient = webClientBuilder.build();

        HandlerFunction<ServerResponse> testHandler = new HandlerFunction<>() { 
            @Override
            public Mono<ServerResponse> handle(ServerRequest request) {

                Mono<String> stringMono = webClient.get().uri(endpoint)
                        .retrieve().bodyToMono(String.class)
                        .flatMap(body -> Mono.just("Modify the response " + body));

                return ServerResponse.ok().contentType(MediaType.TEXT_PLAIN)
                        .body(stringMono, String.class); 
            }
        };
        return RouterFunctions.route(GET("/test-web-client").and(
                accept(MediaType.TEXT_PLAIN)),testHandler::handle);  
    }
}

这就是使用 http://postman-echo.com/get?name=value 就像上面的代码。

Caused by: reactor.blockhound.BlockingOperationError: Blocking call! java.io.FileInputStream#readBytes
    at java.base/java.io.FileInputStream.readBytes(FileInputStream.java) ~[na:na]
    at java.base/java.io.FileInputStream.read(FileInputStream.java:279) ~[na:na]
    at java.base/sun.nio.cs.StreamDecoder.readBytes(StreamDecoder.java:284) ~[na:na]
    at java.base/sun.nio.cs.StreamDecoder.implRead(StreamDecoder.java:326) ~[na:na]
    at java.base/sun.nio.cs.StreamDecoder.read(StreamDecoder.java:178) ~[na:na]
    at java.base/java.io.InputStreamReader.read(InputStreamReader.java:185) ~[na:na]
    at java.base/java.io.BufferedReader.fill(BufferedReader.java:161) ~[na:na]
    at java.base/java.io.BufferedReader.readLine(BufferedReader.java:326) ~[na:na]
    at java.base/java.io.BufferedReader.readLine(BufferedReader.java:392) ~[na:na]
    at io.netty.resolver.dns.UnixResolverDnsServerAddressStreamProvider.parseEtcResolverSearchDomains(UnixResolverDnsServerAddressStreamProvider.java:373) ~[netty-resolver-dns-4.1.58.Final.jar:4.1.58.Final]
    at io.netty.resolver.dns.UnixResolverDnsServerAddressStreamProvider.parseEtcResolverSearchDomains(UnixResolverDnsServerAddressStreamProvider.java:354) ~[netty-resolver-dns-4.1.58.Final.jar:4.1.58.Final]
    at io.netty.resolver.dns.DnsNameResolver.<clinit>(DnsNameResolver.java:137) ~[netty-resolver-dns-4.1.58.Final.jar:4.1.58.Final]
    at io.netty.resolver.dns.DnsNameResolverBuilder.<init>(DnsNameResolverBuilder.java:49) ~[netty-resolver-dns-4.1.58.Final.jar:4.1.58.Final]
    at reactor.netty.transport.NameResolverProvider.newNameResolverGroup(NameResolverProvider.java:405) ~[reactor-netty-core-1.0.3.jar:1.0.3]
    ......

如果将端点修改为使用https,则会发生这种情况: https://postman-echo.com/get?name=value ```
Caused by: reactor.blockhound.BlockingOperationError: Blocking call! java.io.FileInputStream#readBytes
at java.base/java.io.FileInputStream.readBytes(FileInputStream.java) ~[na:na]
at java.base/java.io.FileInputStream.read(FileInputStream.java:279) ~[na:na]
at java.base/java.io.BufferedInputStream.fill(BufferedInputStream.java:252) ~[na:na]
at java.base/java.io.BufferedInputStream.read(BufferedInputStream.java:271) ~[na:na]
at java.base/sun.security.util.DerValue.init(DerValue.java:388) ~[na:na]
at java.base/sun.security.util.DerValue.(DerValue.java:331) ~[na:na]
at java.base/sun.security.util.DerValue.(DerValue.java:344) ~[na:na]
at java.base/sun.security.pkcs12.PKCS12KeyStore.engineLoad(PKCS12KeyStore.java:1993) ~[na:na]
at java.base/sun.security.util.KeyStoreDelegator.engineLoad(KeyStoreDelegator.java:222) ~[na:na]
at java.base/java.security.KeyStore.load(KeyStore.java:1479) ~[na:na]
at java.base/sun.security.ssl.TrustStoreManager$TrustAnchorManager.loadKeyStore(TrustStoreManager.java:365) ~[na:na]
......

a1o7rhls

a1o7rhls1#

这似乎是一个有报道的问题。
修复程序已合并,将以版本发布 4.1.59.Final 截至发稿时,它还没有发布,但是一个计划中的里程碑。

相关问题