Webflux Webclient - 将 HTTP2 请求作为客户端发送到启用 HTTP2 的服务器时出错

Webflux Webclient - Error when sending HTTP2 requests as client to a HTTP2 enabled server

关于向启用 HTTP2 的服务器发送 HTTP2 请求时出现的问题的小问题

原因:io.netty.handler.codec.http2.Http2Exception:第一个收到的帧不是设置。前 5 个字节的十六进制转储:485454502f

设置: 在服务器端,一个 Spring Webflux 应用程序 2.4.2,其中启用了带有 mTLS 的 http2。 java版本是11.netty版本是4.

server.http2.enabled=true
server.ssl.client-auth=need
server.ssl.enabled-protocols=TLSv1.3
server.ssl.enabled=true
server.ssl.key-alias=server
server.ssl.key-password=x
server.ssl.key-store-password=x
server.ssl.key-store-provider=SUN
server.ssl.key-store-type=JKS
server.ssl.key-store=keystore.p12
server.ssl.trust-store-password=x
server.ssl.trust-store-provider=SUN
server.ssl.trust-store-type=JKS
server.ssl.trust-store=truststore.p12

我知道它已成功启用 HTTP2,因为当我卷曲它时,我在卷曲响应上看到了。

* TLSv1.3 (IN), TLS handshake, Newsession Ticket (4):
* Connection state changed (MAX_CONCURRENT_STREAMS == 4294967295)!
< HTTP/2 200

并且在服务器端日志中,我确实看到了 Feb/2021:+0000] "GET /route HTTP/2.0" 200 288448 24 ms

现在,问题

使用Webflux Webclient的客户端,初始化如下:

WebClient.create().mutate().defaultHeader(HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_JSON_VALUE).clientConnector(new ReactorClientHttpConnector(HttpClient.create().protocol(HttpProtocol.H2).wiretap(true).secure(sslContextSpec -> sslContextSpec.sslContext(getSslContext())))).build();

注意.protocol(HttpProtocol.H2)

当使用这个 Webclient 向这个启用了 http2 的服务器发送完全相同的请求时,我看到了这个异常: 第一个收到的帧不是设置。前 5 个字节的十六进制转储:485454502f;

org.springframework.web.reactive.function.client.WebClientRequestException: First received frame was not SETTINGS. Hex dump for first 5 bytes: 485454502f; nested exception is io.netty.handler.codec.http2.Http2Exception: First received frame was not SETTINGS. Hex dump for first 5 bytes: 485454502f
    at org.springframework.web.reactive.function.client.ExchangeFunctions$DefaultExchangeFunction.lambda$wrapException(ExchangeFunctions.java:137) ~[spring-webflux-5.3.3.jar!/:5.3.3]

上网查了一下,485454502f代表HTTP/,但是我的服务器启用了HTTP2!

它不是 gRPC 服务器,只是启用了 HTTP2。

因此,我不明白为什么我会遇到这个问题。

感谢您的帮助。

来自 Spring 团队:

Reactor Netty 提供两种类型的 SslContext 配置:

https://projectreactor.io/docs/netty/release/api/reactor/netty/tcp/SslProvider.SslContextSpec.html

您可以提供 SslContext 或 SslContextBuilder。

解决方案:

要么使用支持 HTTP/2 的配置扩展 SslContext 或者提供 SslContextBuild 和 Reactor Netty 将能够应用一些默认 HTTP/2 配置

我试过了,都成功了(感谢 Spring 团队)