如何将Spring Boot客户端注册至启用HTTPS的Eureka服务器
Eureka HTTPS模式下客户端无法注册问题排查与解决
问题背景
需要搭建HTTPS模式的Eureka注册中心及同模式的Spring Boot客户端微服务,确保两者通信通过TLS加密。
已完成操作:
- 生成自签名SSL证书并导入PKCS12密钥库
- 在Eureka服务端和客户端的
application.properties中配置密钥库信息 - Eureka服务和客户端均可通过HTTPS正常访问
当前问题:客户端无法注册到Eureka服务器(HTTP模式下注册正常),抛出如下错误:
2023-01-17 14:40:53,529 ERROR c.n.d.DiscoveryClient [DiscoveryClient-HeartbeatExecutor-0] DiscoveryClient_MY-MICROSERVICE/localhost:my-microservice:8079 - was unable to send heartbeat! com.netflix.discovery.shared.transport.TransportException: Cannot execute request on any known server at com.netflix.discovery.shared.transport.decorator.RetryableEurekaHttpClient.execute(RetryableEurekaHttpClient.java:112) ~[eureka-client-1.10.17.jar!/:1.10.17] at com.netflix.discovery.shared.transport.decorator.EurekaHttpClientDecorator.sendHeartBeat(EurekaHttpClientDecorator.java:89) ~[eureka-client-1.10.17.jar!/:1.10.17] at com.netflix.discovery.shared.transport.decorator.EurekaHttpClientDecorator$3.execute(EurekaHttpClientDecorator.java:92) ~[eureka-client-1.10.17.jar!/:1.10.17] at com.netflix.discovery.shared.transport.decorator.SessionedEurekaHttpClient.execute(SessionedEurekaHttpClient.java:77) ~[eureka-client-1.10.17.jar!/:1.10.17] at com.netflix.discovery.shared.transport.decorator.EurekaHttpClientDecorator.sendHeartBeat(EurekaHttpClientDecorator.java:89) ~[eureka-client-1.10.17.jar!/:1.10.17] at com.netflix.discovery.DiscoveryClient.renew(DiscoveryClient.java:893) ~[eureka-client-1.10.17.jar!/:1.10.17] at com.netflix.discovery.DiscoveryClient$HeartbeatThread.run(DiscoveryClient.java:1457) ~[eureka-client-1.10.17.jar!/:1.10.17] at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:539) ~[?:?] at java.util.concurrent.FutureTask.run(FutureTask.java:264) ~[?:?] at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1136) ~[?:?] at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:635) ~[?:?] at java.lang.Thread.run(Thread.java:833) ~[?:?]
已尝试的解决措施:
- 使用
keytool将自签名证书添加至JDK的jdk-home\lib\security\cacerts文件 - 更新客户端
eureka.client.serviceUrl.defaultZone为HTTPS地址,但问题未解决
配置文件
Eureka服务端application.properties
server.port=8761 server.ssl.enabled: true server.ssl.key-store: src/main/resources/springboot.p12 server.ssl.key-store-password: MyPassword server.ssl.key-store-type: pkcs12 server.ssl.key-alias: springboot security.require-ssl: true spring.application.name=my-service-registry eureka.client.register-with-eureka=false eureka.client.fetch-registry=false eureka.instance.nonSecurePortEnabled=false eureka.instance.securePortEnabled=true eureka.instance.securePort=${server.port} eureka.dashboard.enabled=true logging.level.com.netflix.eureka=OFF logging.level.com.netflix.discovery=OFF
客户端application.properties
server.port = 8079 server.ssl.enabled: true server.ssl.key-store: src/main/resources/springboot.p12 server.ssl.key-store-password: MyPassword server.ssl.key-store-type: pkcs12 server.ssl.key-alias: springboot security.require-ssl: true spring.application.name=my-microservice eureka.client.securePortEnabled = true eureka.client.serviceUrl.defaultZone = https://localhost:8761/eureka eureka.instance.prefer-ip-address = true eureka.instance.securePortEnabled = true eureka.instance.nonSecurePortEnabled = false
运行环境与依赖
- 运行环境:Windows系统,JDK版本为jdk-18.0.2.1
- Spring Cloud版本:2021.0.3
Eureka服务端依赖
spring-cloud-starter-netflix-eureka-server 3.1.4 spring-boot-starter-tomcat 2.7.3 spring-boot-starter-web 2.7.3 spring-core 5.3.22 spring-boot-starter-test 2.7.0 spring-web 5.3.23 spring-security-crypto 5.7.5 spring-security-core 5.7.5 spring-security-web 5.7.5 spring-security-config 5.7.5 spring-boot-starter-security 2.7.5 spring-boot-starter 2.7.0 spring-boot-starter-log4j2 2.7.0
客户端依赖
spring-boot-starter-web 2.7.0 spring-boot-starter-test 2.7.0 spring-boot-starter 2.7.0 spring-boot-starter-log4j2 2.7.0 spring-security-crypto 5.7.5
解决方案
1. 补充客户端核心依赖
当前客户端缺失spring-cloud-starter-netflix-eureka-client,这是注册到Eureka的必需依赖,需添加:
<!-- Maven示例,Gradle对应调整 --> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId> <version>3.1.4</version> </dependency>
2. 配置Eureka客户端SSL信任库
即使证书已加入JDK cacerts,Eureka客户端可能未正确加载,需在客户端application.properties中显式配置:
# 指定Eureka客户端的SSL密钥库与信任库(自签名证书可复用同一个p12文件) eureka.client.tls.key-store=src/main/resources/springboot.p12 eureka.client.tls.key-store-password=MyPassword eureka.client.tls.key-store-type=PKCS12 eureka.client.tls.trust-store=src/main/resources/springboot.p12 eureka.client.tls.trust-store-password=MyPassword eureka.client.tls.trust-store-type=PKCS12
3. 调整Eureka服务端安全配置
由于引入Spring Security,Eureka服务端默认开启CSRF防护和表单登录,会拦截客户端注册请求。需添加安全配置类放行Eureka端点:
import org.springframework.security.config.annotation.web.builders.HttpSecurity; import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity; import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter; @EnableWebSecurity public class WebSecurityConfig extends WebSecurityConfigurerAdapter { @Override protected void configure(HttpSecurity http) throws Exception { // 关闭CSRF,放行Eureka相关端点 http.csrf().ignoringAntMatchers("/eureka/**") .and() .authorizeRequests() .antMatchers("/eureka/**").permitAll() .anyRequest().authenticated() .and() .requiresChannel() .anyRequest().requiresSecure(); // 强制HTTPS访问 } }
4. 确认证书CN与访问域名匹配
自签名证书的CN(通用名称)必须为localhost(客户端用localhost访问Eureka),若不匹配需重新生成证书:
keytool -genkeypair -alias springboot -keyalg RSA -keysize 2048 -storetype PKCS12 -keystore springboot.p12 -validity 3650 -dname "CN=localhost, OU=Dev, O=MyCompany, L=City, ST=Province, C=CN"
5. 开启日志排查细节
临时开启Eureka日志,查看具体错误原因:
在服务端和客户端application.properties中修改:
logging.level.com.netflix.eureka=DEBUG logging.level.com.netflix.discovery=DEBUG
内容的提问来源于stack exchange,提问作者cool_cucumber
相关产品推荐
相关产品推荐

