Spring Boot 2 Webflux+Netty+HTTP2配置SSL证书报错求助
当前配置里有三处明确错误,逐点修正后即可让WebFlux Netty正常跑通带SSL的HTTP2服务:
1. YAML配置层级嵌套错误,SSL配置完全未生效
这是导致当前问题的最核心原因,和Reactor栈的特性无关,纯粹是写配置时的缩进失误:你在application.yaml里多嵌套了一层server节点,导致所有SSL相关参数的实际读取路径变成了server.server.ssl,Spring Boot根本无法识别这部分配置,最终Netty启动时直接运行了明文HTTP服务。
这也完全匹配你测试时的现象:用HTTP请求能正常拿到Actuator数据,用HTTPS请求就报wrong version number——你拿着TLS协议的握手报文去打明文HTTP端口,服务端自然无法识别协议版本。
错误的配置结构片段:
server: port: 8443 shutdown: graceful http2: enabled: true server: # 多余的嵌套层 ssl: enabled: true # ... 其余SSL配置
正确的配置写法:
删掉多余的嵌套层,把所有SSL参数直接放在server节点下:
server: port: 8443 shutdown: graceful http2: enabled: true ssl: enabled: true key-store-type: PKCS12 key-store: classpath:keystore.p12 key-store-password: password key-alias: localdev
改完后可以用openssl s_client -connect localhost:8443快速验证,如果能正常返回你之前生成的证书信息,说明SSL已经正常开启。
2. Gradle依赖坐标写法错误,HTTP2依赖的BoringSSL组件未加载
你当前的Netty静态SSL组件依赖写法存在语法问题:
// 错误写法:连续两个冒号导致版本位为空,依赖无法正常解析 runtimeOnly ("io.netty:netty-tcnative-boringssl-static::${osdetector.classifier}")
这种写法会让Gradle把系统架构匹配值直接塞到版本号字段,根本拉不到对应平台的静态加密组件。而Netty要实现HTTP2 over TLS必须依赖这个组件提供ALPN协议协商能力,缺失组件就算SSL配置正确,也无法完成HTTP2的协议升级。
正确的依赖写法:
让Spring Boot BOM自动管理组件版本,仅指定对应平台的分类器:
runtimeOnly "io.netty:netty-tcnative-boringssl-static" { artifact { // 匹配当前系统的静态组件包 classifier = osdetector.classifier } }
3. curl请求命令参数顺序错误
你当前执行的curl命令把--http2参数放在了--cert的参数位置中间,导致curl把--http2识别成证书路径,根本读不到正确的证书配置:
# 错误写法 curl --cert --http2 localhost+1.pem --key localhost+1-key.pem --insecure https://localhost:8443/actuator/health
正确的curl命令顺序:
curl --http2 --cert localhost+1.pem --key localhost+1-key.pem --insecure https://localhost:8443/actuator/health
内容的提问来源于stack exchange,提问作者RST

