一、核心概念
1. Eureka 架构简述
Eureka 是 Netflix 开源的服务注册与发现组件,广泛用于 Spring Cloud 微服务架构中。其核心角色包括:
- Eureka Server:服务注册中心,负责维护服务实例的注册信息。
- Eureka Client:服务提供者和服务消费者,向 Eureka Server 注册自身,并发现其他服务。
2. 心跳检测(Heartbeat / Renewal)
- 定义:Eureka Client 定期(默认每30秒)向 Eureka Server 发送“心跳”(Renew)请求,表明自己“还活着”。
- 作用:Server 通过心跳判断服务实例是否健康。若在一定时间内未收到心跳,Server 会将该实例从注册表中剔除(默认90秒未收到心跳即认为失效)。
- 协议:基于 HTTP 的 REST 调用。
3. 自我保护机制(Self-Preservation Mode)
- 触发条件:当 Eureka Server 在某个统计周期内(默认15分钟)收到的心跳失败率超过阈值(默认85%),即“预期心跳数 × 0.85”时,进入自我保护模式。
- 行为:
- 不再剔除“长时间未收到心跳”的服务实例。
- 控制台显示
EMERGENCY! EUREKA IS IN SELF PRESERVATION MODE
。
- 目的:防止因网络分区、短暂抖动等导致大量健康服务被误删,保障系统可用性。
✅ 一句话总结:
心跳是“我还活着”的信号;自我保护是“我怀疑网络有问题,先别删服务” 的防御机制。
二、操作步骤(详细实践)
步骤 1:搭建 Eureka Server
1.1 创建 Spring Boot 项目,添加依赖
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-server</artifactId>
</dependency>
</dependencies>
1.2 配置 application.yml
server:
port: 8761
eureka:
instance:
hostname: localhost
client:
register-with-eureka: false # Eureka Server 不注册自己
fetch-registry: false # 不从其他节点拉取注册信息(单机)
service-url:
defaultZone: http://${eureka.instance.hostname}:${server.port}/eureka/
server:
enable-self-preservation: true # 开启自我保护(默认开启)
eviction-interval-timer-in-ms: 60000 # 清理失效实例的间隔(默认60秒)
1.3 启动类添加注解
@SpringBootApplication
@EnableEurekaServer
public class EurekaServerApplication {
public static void main(String[] args) {
SpringApplication.run(EurekaServerApplication.class, args);
}
}
启动后访问:http://localhost:8761
,查看 Eureka 控制台。
步骤 2:创建 Eureka Client(服务提供者)
2.1 添加依赖
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
</dependency>
</dependencies>
2.2 配置 application.yml
server:
port: 8081
spring:
application:
name: service-provider
eureka:
client:
service-url:
defaultZone: http://localhost:8761/eureka/
instance:
lease-renewal-interval-in-seconds: 30 # 心跳间隔(默认30秒)
lease-expiration-duration-in-seconds: 90 # 服务失效时间(默认90秒)
2.3 启动类
@SpringBootApplication
@EnableEurekaClient
public class ServiceProviderApplication {
public static void main(String[] args) {
SpringApplication.run(ServiceProviderApplication.class, args);
}
}
2.4 添加一个简单接口
@RestController
public class ProviderController {
@GetMapping("/hello")
public String hello() {
return "Hello from Provider!";
}
}
步骤 3:验证心跳与自我保护
3.1 启动服务
- 启动 Eureka Server(8761)
- 启动 service-provider(8081)
3.2 查看控制台
- Eureka 控制台显示
1 INSTANCE(S) OF 1 SERVICE(S) UP
,表示服务已注册。 - 日志中可看到 Client 每 30 秒发送一次心跳:
Renew: service-provider sending renewal to eureka-server
3.3 触发自我保护(模拟网络问题)
- 停止所有 Eureka Client(或断网)。
- 等待一段时间(约2-3分钟),观察 Eureka Server 控制台:
- 出现红色警告:EMERGENCY! EUREKA IS IN SELF PRESERVATION MODE
- 已注册的服务不会立即消失,而是保留。
⚠️ 注意:自我保护是“宁可错保,不可错删”的策略。
三、常见错误与解决方案
错误现象 | 原因 | 解决方案 |
---|---|---|
Cannot execute request on any known server |
Client 无法连接 Eureka Server | 检查 eureka.client.service-url.defaultZone 是否正确,防火墙是否开放 |
服务注册成功但不显示 | 配置错误或网络问题 | 检查 spring.application.name 是否一致,Server 是否启用 |
心跳频繁失败 | 网络延迟高或 GC 停顿 | 调整 lease-renewal-interval-in-seconds 和 lease-expiration-duration-in-seconds |
自我保护频繁触发 | 心跳间隔过短或实例过多 | 优化网络,增加实例,或适当调大失效时间 |
四、注意事项
心跳间隔与失效时间:
- 默认 30 秒心跳,90 秒失效。生产环境可根据网络质量调整,如改为 15/45 秒。
- 设置过短会增加 Server 压力,过长则故障发现慢。
自我保护不可关闭(生产环境):
eureka.server.enable-self-preservation=false
仅用于测试,生产环境必须开启。
多节点部署:
- 生产环境应部署 Eureka Server 集群(至少3节点),避免单点故障。
客户端缓存:
- Eureka Client 会缓存服务列表,默认每30秒更新一次(
eureka.client.registry-fetch-interval-seconds
)。
- Eureka Client 会缓存服务列表,默认每30秒更新一次(
五、使用技巧
自定义实例ID:
eureka: instance: instance-id: ${spring.application.name}:${spring.application.instance_id:${server.port}}
健康检查集成: 使用 Spring Boot Actuator,Eureka 会自动检测
/actuator/health
状态。优雅下线: 在服务关闭前调用:
@Autowired private EurekaClient eurekaClient; public void shutdown() { eurekaClient.shutdown(); }
或发送 DELETE 请求到 Eureka Server。
六、最佳实践与性能优化
1. 集群部署 Eureka Server
- 至少3个节点,相互注册,提高可用性。
- 配置:
eureka: client: service-url: defaultZone: http://peer1:8761/eureka/,http://peer2:8762/eureka/,http://peer3:8763/eureka/
2. 调整心跳与清理频率
# Client 配置
eureka:
instance:
lease-renewal-interval-in-seconds: 15
lease-expiration-duration-in-seconds: 45
# Server 配置
eureka:
server:
eviction-interval-timer-in-ms: 30000 # 每30秒清理一次
3. 监控与告警
- 集成 Prometheus + Grafana 监控 Eureka 状态。
- 对“自我保护模式”触发设置告警。
4. 与 Ribbon/Feign 集成
- Feign 默认集成 Ribbon,自动从 Eureka 获取服务列表并负载均衡。
5. 性能优化建议
- 避免注册过多小服务,合理拆分。
- 使用
@RefreshScope
动态刷新配置,减少重启。 - 定期清理已下线服务(手动或脚本)。
七、总结
机制 | 作用 | 推荐配置 |
---|---|---|
心跳检测 | 维持服务存活状态 | 15~30秒 |
服务失效 | 清理不健康实例 | 45~90秒 |
自我保护 | 防止误删服务 | 必须开启 |
集群部署 | 提高可用性 | ≥3节点 |
✅ 实践建议:
- 开发环境可用单节点 + 关闭自我保护。
- 生产环境必须集群 + 开启自我保护 + 合理调参。
掌握 Eureka 的心跳与自我保护机制,是构建高可用微服务系统的基石。建议在测试环境中多模拟故障场景(如断网、GC、重启),加深理解。