You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Spring Cloud微服务全服务启用SSL后网关请求报TLS要求错误求助

Spring Cloud Eureka 微服务全SSL配置问题排查与解决方案

问题场景

基于Spring Cloud Eureka的微服务项目包含注册中心、Cloud Gateway、service-a、service-b四个组件,已为所有组件配置SSL,但通过网关(8849端口)请求service-a/service-b时,收到错误:

Bad Request

This combination of host and port requires TLS.

仅网关启用SSL、禁用服务端SSL时一切正常,同时想了解无服务间通信时,仅网关启用SSL是否为最佳实践。使用版本:Spring Boot 3.3.4、Java 21。

各组件SSL配置如下:

注册中心 application.properties

spring.application.name=serviceregistry
server.port=8848

eureka.client.register-with-eureka=false
eureka.client.fetch-registry=false

eureka.instance.prefer-ip-address=false
eureka.instance.hostname=localhost
eureka.instance.lease-expiration-duration-in-seconds=30
eureka.instance.lease-renewal-interval-in-seconds=15

# SSL
server.ssl.enabled=true
server.ssl.key-store-type=PKCS12
server.ssl.key-store=<ROOT_PATH>\\sslkey24.p12
server.ssl.key-store-password=PASSWORD
server.ssl.key-alias=ALIAS

Cloud Gateway application.yml

server:
    port: 8849
    ssl:
        enabled: true
        key-store-type: PKCS12
        key-store: <ROOT_PATH>\\sslkey24.p12
        key-store-password: PASSWORD
        key-alias: ALIAS

spring:
    application:
        name: cloud-gateway
    cloud:
        discovery:
            enabled: true
        gateway:
            routes:
                - id: service-a
                  uri: lb://service-a
                  predicates:
                    - Path=/service-a/**

                - id: service-b
                  uri: lb://service-b
                  predicates:
                    - Path=/service-b/**
eureka:
    client:
        register-with-eureka: true
        fetch-registry: true
        service-url:
            defaultZone: <DISCOVERY_SERVER_URL>/eureka
    instance:
        hostname: localhost
        prefer-ip-address: false
        ip-address: 127.0.0.1
        lease-expiration-duration-in-seconds: 30
        lease-renewal-interval-in-seconds: 15

Service A application.properties

spring.application.name=service-a

server.port=8611
server.servlet.context-path=/service-a
server.error.include-binding-errors: always
server.error.include-stacktrace=never


server.ssl.enabled=true
server.ssl.key-store-type=PKCS12
server.ssl.key-store=<ROOT_PATH>\\sslkey24.p12
server.ssl.key-store-password=PASSWORD
server.ssl.key-alias=ALIAS

# Cloud Gateway
eureka.instance.hostname=localhost
eureka.instance.prefer-ip-address=false
eureka.instance.ip-address=127.0.0.1
eureka.client.serviceUrl.defaultZone=<DISCOVERY_SERVER_URL>/eureka
#eureka.instance.secure-port-enabled=true
#eureka.instance.secure-port=8611
eureka.instance.lease-expiration-duration-in-seconds=30
eureka.instance.lease-renewal-interval-in-seconds=15

Service B application.properties

spring.application.name=service-b
server.port=8612
server.servlet.context-path=/service-b

# Cloud Gateway
eureka.instance.hostname=localhost
eureka.instance.prefer-ip-address=false
eureka.instance.ip-address=127.0.0.1
eureka.client.serviceUrl.defaultZone=<DISCOVERY_SERVER_URL>/eureka
eureka.instance.lease-expiration-duration-in-seconds=30
eureka.instance.lease-renewal-interval-in-seconds=15

# SSL
server.ssl.enabled=true
server.ssl.key-store-type=PKCS12
server.ssl.key-store=<ROOT_PATH>\\sslkey24.p12
server.ssl.key-store-password=PASSWORD
server.ssl.key-alias=ALIAS

错误根因

service-a、service-b启用SSL后仅监听HTTPS端口,但当前配置中,服务未向Eureka注册安全端口(HTTPS端口),也未标记实例为安全实例。导致网关通过服务发现获取到的是服务的普通HTTP端口地址,用HTTP协议请求已启用SSL的服务,服务端要求TLS连接,因此抛出该错误。

解决方案

1. 配置服务向Eureka注册安全端口

在service-a和service-b的application.properties中,启用安全端口注册并指定端口,同时禁用非安全端口:

# Service A 新增配置
eureka.instance.secure-port-enabled=true
eureka.instance.secure-port=8611
eureka.instance.non-secure-port-enabled=false

# Service B 新增配置
eureka.instance.secure-port-enabled=true
eureka.instance.secure-port=8612
eureka.instance.non-secure-port-enabled=false

配置后Eureka会将服务实例地址注册为HTTPS协议,网关通过lb://service-a调用时会自动使用HTTPS请求服务。

2. 配置网关信任服务端证书(自签名证书场景)

如果使用自签名SSL证书,网关需要配置信任存储来信任服务端证书,否则会出现SSL握手失败。在网关的application.yml中添加:

server:
  ssl:
    # 原有SSL配置不变
    trust-store-type: PKCS12
    trust-store: <ROOT_PATH>\\sslkey24.p12 # 与服务端同一份证书或包含根证书的存储
    trust-store-password: PASSWORD

3. 显式指定网关路由协议(可选)

若上述配置后仍有问题,可显式指定网关路由的URI为HTTPS协议:

spring:
  cloud:
    gateway:
      routes:
        - id: service-a
          uri: lb:https://service-a
          predicates:
            - Path=/service-a/**
        - id: service-b
          uri: lb:https://service-b
          predicates:
            - Path=/service-b/**

最佳实践解答

当不存在服务间内部通信时,仅在网关启用SSL、禁用内部服务SSL是行业常见的最佳实践,原因如下:

  • 降低配置复杂度:无需为每个内部服务配置SSL证书、信任存储等,减少运维成本。
  • 减少性能开销:内部网络的SSL握手和加密解密会带来额外性能损耗,内部网络相对安全的情况下可省略。
  • 满足外部安全需求:网关作为对外入口,启用SSL即可保证外部通信的安全性,内部服务在可信网络环境下无需额外加密。

但如果内部网络存在安全风险(如多租户环境、跨部门共享网络),或有合规要求(如金融、医疗行业),则需要为内部服务也启用SSL,确保端到端的安全。


内容的提问来源于stack exchange,提问作者Shimul

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.16 02:50:04