Spring Cloud Gateway配置HTTPS后,微服务内部调用报错?手把手教你解决那个恼人的NotSslRecordException
Spring Cloud Gateway HTTPS配置后的微服务通信故障排查指南当开发者为Spring Cloud Gateway配置HTTPS后常常会遇到一个令人头疼的问题网关转发到微服务的请求突然失败控制台抛出NotSslRecordException异常。本文将深入分析这一问题的根源并提供两种经过验证的解决方案帮助开发者快速恢复系统正常运行。1. 问题现象与根源分析典型的错误场景表现为外部客户端通过HTTPS成功访问网关但网关转发到后端微服务时出现连接失败。查看日志会发现类似如下的异常堆栈io.netty.handler.ssl.NotSslRecordException: not an SSL/TLS record at io.netty.handler.ssl.SslHandler.decodeJdkCompatible(SslHandler.java:1178) at io.netty.handler.ssl.SslHandler.decode(SslHandler.java:1243)根本原因在于协议不匹配客户端与网关之间建立了HTTPS加密连接网关默认会将请求原样转发包括协议类型后端微服务通常只配置了HTTP服务当HTTPS请求到达HTTP服务时服务端无法解密数据流导致SSL解析失败2. 解决方案一显式指定后端协议最直接的解决方法是在路由配置中强制指定后端服务使用HTTP协议spring: cloud: gateway: routes: - id: service-route uri: lb:http://service-name # 关键在lb:http://前缀 predicates: - Path/api/**实现原理lb:http://前缀会覆盖默认的协议继承行为LoadBalancerClientFilter会根据该前缀创建HTTP请求实际转发时剥离SSL加密层以明文与后端通信优缺点对比方案特点显式指定HTTP全链路HTTPS配置复杂度低只需修改路由高需配置所有服务安全性网关-服务间明文全程加密性能开销低中等加解密消耗适用场景内部网络可信环境对安全要求严格的场景3. 解决方案二全链路HTTPS配置对于需要更高安全性的场景建议让后端服务也启用HTTPS后端服务配置示例server: ssl: enabled: true key-store: classpath:keystore.p12 key-store-password: changeit key-store-type: PKCS12网关路由对应调整uri: lb:https://service-name证书管理建议使用同一CA签发的证书集群配置证书自动续期机制考虑使用服务网格(如Istio)统一管理mTLS4. 高级调试技巧当问题仍然出现时可通过以下方法深入排查网络抓包分析tcpdump -i any -w gateway.pcap port 8080关键检查点网关转发的实际目标地址请求头中的X-Forwarded-Proto值服务端SSL握手过程日志级别调整logging: level: org.springframework.cloud.gateway: DEBUG reactor.netty: DEBUG5. 架构设计思考根据实际业务需求选择合适的安全策略混合协议架构客户端(HTTPS) → 网关(HTTPS) → 服务(HTTP)全加密架构客户端(HTTPS) → 网关(HTTPS) → 服务(HTTPS)服务网格方案客户端 → Ingress(HTTPS) → Sidecar(mTLS) → 服务在实际项目中我们曾遇到一个典型案例某金融系统在测试环境运行正常但上线后出现间歇性NotSslRecordException。最终发现是某个Pod的注解配置遗漏了sidecar.istio.io/inject: true导致部分请求未经过Sidecar加密。