JHipster网关调用HTTPS微服务失败(NoHttpResponseException)解决方案
解决JHipster网关调用HTTPS微服务时的NoHttpResponseException问题
这个问题我之前帮人排查过好几次,org.apache.http.NoHttpResponseException在JHipster网关调用HTTPS微服务时出现,大多是SSL信任问题、配置不匹配或者网络连通性问题导致的,给你一步步拆解解决方法:
1. 先确认微服务本身的HTTPS服务正常
首先得排除微服务自身的问题,别一开始就盯着网关:
- 检查微服务
application-prod.yml里的server.ssl配置是否完整,比如:server: ssl: key-store: classpath:your-keystore.p12 key-store-password: your-secure-password key-store-type: PKCS12 key-alias: your-key-alias enabled: true port: 52568 # 确保端口和你报错里的一致 - 手动验证微服务的HTTPS端点是否可用:用
curl -k https://172.24.36.5:52568/actuator/health(-k参数是临时忽略证书验证,先确认服务能正常响应),或者用浏览器访问这个地址,看是否能拿到正常返回。
2. 让网关信任微服务的SSL证书
这是最常见的原因——网关不信任微服务的证书,导致SSL握手失败,最终抛出无响应异常:
情况A:微服务用自签名证书
你需要把微服务的证书导入网关的信任存储:
- 导出微服务的证书:
从微服务的密钥库中导出证书文件:
执行时输入密钥库的密码即可生成keytool -export -alias your-key-alias -keystore your-keystore.p12 -storetype PKCS12 -file microservice-cert.crtmicroservice-cert.crt文件。 - 将证书导入网关的信任存储:
- 方案1:导入到JVM默认信任库(适合所有基于JVM的应用):
默认密码是keytool -import -alias microservice-cert -file microservice-cert.crt -keystore $JAVA_HOME/jre/lib/security/cacertschangeit,按照提示输入yes确认信任该证书。 - 方案2:给网关配置自定义信任库(更灵活,不影响其他应用):
先把证书打包成PKCS12格式的信任库:
然后在网关的keytool -importcert -file microservice-cert.crt -alias microservice-cert -keystore gateway-truststore.p12 -storetype PKCS12 -storepassword your-truststore-passwordapplication-prod.yml里添加配置:spring: cloud: gateway: httpclient: ssl: trust-store: classpath:gateway-truststore.p12 trust-store-password: your-truststore-password trust-store-type: PKCS12
- 方案1:导入到JVM默认信任库(适合所有基于JVM的应用):
情况B:微服务用CA签发的证书
如果是公共CA签发的证书,网关的JVM默认信任库通常已经包含根证书,不用额外操作;如果是私有CA签发的,需要把私有CA的根证书导入网关的信任存储,步骤和上面自签名证书的导入方法一致。
3. 调整网关HTTP客户端的超时与重试策略
有时候NoHttpResponseException是因为连接超时、SSL握手超时或者服务端响应慢导致的,可以通过配置超时和重试来缓解:
在网关的application-prod.yml里添加:
spring: cloud: gateway: httpclient: connect-timeout: 10000 # 连接超时10秒 response-timeout: 30000 # 响应超时30秒 ssl: handshake-timeout-millis: 10000 # SSL握手超时10秒 routes: - id: your-microservice-route uri: https://172.24.36.5:52568 # 确保是HTTPS开头 predicates: - Path=/api/your-microservice/** filters: - name: Retry args: retries: 3 # 重试3次 methods: GET,POST # 针对GET和POST请求重试 backoff: firstBackoff: 100ms # 第一次重试间隔100ms maxBackoff: 500ms # 最大重试间隔500ms multiplier: 2 # 间隔倍数 exceptions: - org.apache.http.NoHttpResponseException # 指定针对该异常重试
4. 检查网络连通性
别忽略最基础的网络问题:
- 在网关所在服务器上,用
telnet 172.24.36.5 52568或者nc -zv 172.24.36.5 52568测试端口是否开放,能连通的话会提示成功; - 如果是Docker容器部署,确认网关和微服务容器在同一个Docker网络里,或者端口映射正确;
- 检查是否有防火墙、安全组规则阻止了网关到微服务的52568端口的HTTPS流量。
5. 验证网关路由配置的正确性
最后再检查一遍网关的路由配置:
- 确保路由的
uri是https://开头,而不是http://(很多人在这里踩坑); - 确认
predicates和filters配置正确,比如路径重写规则是否匹配微服务的实际接口路径。
最后一招:开启DEBUG日志排查细节
如果以上步骤都试过还是没解决,开启网关的DEBUG日志,查看SSL握手的详细过程,定位具体问题:
logging: level: org.springframework.cloud.gateway: DEBUG org.apache.http: DEBUG javax.net.ssl: DEBUG
日志里会显示SSL握手的每一步,比如证书是否被信任、握手失败的具体原因等。
内容的提问来源于stack exchange,提问作者Michele Mazza
相关产品推荐
相关产品推荐

