Spring Cloud Eureka服务注册案例

wen java案例 1

本文目录导读:

Spring Cloud Eureka服务注册案例

  1. 目录导读
  2. 为什么需要服务注册中心?
  3. Eureka核心概念
  4. 环境准备与依赖搭建
  5. 服务注册中心(Server)代码实现
  6. 服务提供者(Client)注册实战
  7. 服务消费者(Consumer)发现与调用
  8. 高可用集群配置
  9. 常见问题与FAQ

Spring Cloud Eureka服务注册实战:从零搭建高可用微服务注册中心

目录导读

  1. 为什么需要服务注册中心? —— 微服务架构的“通讯录”痛点
  2. Eureka核心概念 —— 服务提供者、消费者与注册中心的三角恋
  3. 环境准备与依赖搭建 —— Maven依赖、启动类注解全解析
  4. 服务注册中心(Server)代码实现 —— 三步搞定Eureka Server
  5. 服务提供者(Client)注册实战 —— 心跳续约与元数据配置
  6. 服务消费者(Consumer)发现与调用 —— RestTemplate + @LoadBalanced
  7. 高可用集群配置 —— 多节点互相注册,避免单点故障
  8. 常见问题与FAQ —— 服务注册不上?心跳超时?一文排雷

为什么需要服务注册中心?

在传统单体应用中,服务间调用通过IP+端口直接写死,但在微服务架构下,服务实例会动态扩缩容、重启迁移,硬编码地址会彻底崩盘。Eureka作为Netflix开源的服务注册中心,相当于整个微服务体系的“实时通讯录”:

  • 每个服务启动时向Eureka Server登记自己的IP、端口、服务名
  • 服务消费者从Eureka拉取可用服务列表,实现客户端负载均衡
  • 通过心跳机制(默认30秒)自动剔除故障节点

关键点:Eureka更偏向“AP”模式(高可用优先),适合非强一致性的业务场景,而Zookeeper则是“CP”模式。


Eureka核心概念

角色 说明 关键动作
Eureka Server 注册中心,存储服务实例信息 接收心跳、提供查询接口、剔除过期实例
Eureka Client (Provider) 提供业务的微服务 注册、续约(心跳)、下线通知
Eureka Client (Consumer) 调用其他服务的微服务 拉取注册表、缓存、更新

核心配置标签

  • eureka.client.register-with-eureka:是否注册自己到注册中心
  • eureka.client.fetch-registry:是否拉取注册表缓存到本地

环境准备与依赖搭建

创建两个Spring Boot模块(这里使用2.3.x版本,兼容Spring Cloud Hoxton.SR12):

父POM核心依赖管理

<dependencyManagement>
    <dependencies>
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-dependencies</artifactId>
            <version>Hoxton.SR12</version>
            <type>pom</type>
            <scope>import</scope>
        </dependency>
    </dependencies>
</dependencyManagement>

Eureka Server模块依赖

<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-netflix-eureka-server</artifactId>
</dependency>

Provider/Consumer依赖

<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
</dependency>

注意:Spring Boot 2.4+需显式指定spring-boot-starter-web,否则可能报错。


服务注册中心(Server)代码实现

Step 1:启动类添加注解

@SpringBootApplication
@EnableEurekaServer
public class EurekaServerApplication {
    public static void main(String[] args) {
        SpringApplication.run(EurekaServerApplication.class, args);
    }
}

Step 2:application.yml配置

server:
  port: 8761
eureka:
  instance:
    hostname: localhost
  client:
    register-with-eureka: false  # 不注册自己
    fetch-registry: false        # 不拉取注册表
  server:
    enable-self-preservation: false  # 开发期关闭自我保护,测试更直观

Step 3:启动并访问
浏览器输入http://localhost:8761,即可看到Eureka的Web控制台,Instances currently registered with Eureka”列表为空。


服务提供者(Client)注册实战

启动类注解

@SpringBootApplication
@EnableEurekaClient
public class ProviderApplication { ... }

application.yml

server:
  port: 8081
spring:
  application:
    name: order-service   # 服务名,消费者根据此名调用
eureka:
  client:
    service-url:
      defaultZone: http://localhost:8761/eureka/
  instance:
    prefer-ip-address: true           # 注册时使用IP而不是主机名
    instance-id: ${spring.cloud.client.ip-address}:${server.port}
    lease-renewal-interval-in-seconds: 30   # 心跳间隔
    lease-expiration-duration-in-seconds: 90 # 超时剔除时间

写一个测试接口

@RestController
public class OrderController {
    @GetMapping("/order/info")
    public String getOrder() {
        return "订单服务-8081";
    }
}

启动后,Eureka控制台立刻出现ORDER-SERVICE,状态为“UP”,此时可测试心跳续约:日志中会每30秒打印DiscoveryClient_ORDER-SERVICE - Heartbeat


服务消费者(Consumer)发现与调用

关键步骤:注入RestTemplate并加@LoadBalanced实现负载均衡。

@SpringBootApplication
@EnableEurekaClient
public class ConsumerApplication {
    @Bean
    @LoadBalanced   // 关键:启用Ribbon负载均衡,自动解析服务名
    public RestTemplate restTemplate() {
        return new RestTemplate();
    }
    // main方法略
}

Controller调用

@RestController
public class CallController {
    @Autowired
    private RestTemplate restTemplate;
    @GetMapping("/call")
    public String call() {
        // 直接使用服务名,而非IP+端口
        String result = restTemplate.getForObject(
            "http://order-service/order/info", String.class);
        return "消费者调用结果: " + result;
    }
}

验证:启动Consumer(端口8082),访问http://localhost:8082/call,返回“订单服务-8081”,若启动多个Provider实例,Ribbon会轮询分发。


高可用集群配置

单节点注册中心一旦宕机,整个微服务列表将不可用,生产环境必须搭建集群:

创建两个Eureka Server(8761、8762),互相注册:

Server-A配置

server:
  port: 8761
eureka:
  client:
    service-url:
      defaultZone: http://peer2:8762/eureka/   # 注册到另一节点

Server-B配置

server:
  port: 8762
eureka:
  client:
    service-url:
      defaultZone: http://peer1:8761/eureka/

Provider的defaultZone同样配置多个地址,用逗号隔开:http://peer1:8761/eureka/,http://peer2:8762/eureka/,这样任意一个注册中心宕机,服务仍可注册和发现


常见问题与FAQ

Q1:服务注册失败,控制台报错“Connection refused”
检查Eureka Server端口是否开放,且Provider端的defaultZone地址路径必须包含/eureka/,且末尾反斜杠不能漏。

Q2:服务明明已停止,但Eureka控制台仍显示UP
这是自我保护机制(默认开启),开发建议设为false,生产环境则需关注:

eureka:
  server:
    enable-self-preservation: false

但注意生产关闭有导致误剔除的风险,需结合监控。

Q3:消费者调用时出现java.net.UnknownHostException: order-service
根本原因:RestTemplate未加@LoadBalanced,导致Spring无法将服务名解析成实际IP,确保注解已加,且引入了spring-cloud-starter-netflix-ribbon(通常随Eureka Client自带)。

Q4:多个服务实例,但负载均衡不生效?
检查是否所有实例的spring.application.name完全相同,Ribbon根据名称+实例数轮询,名称不同会被视为不同服务。

Q5:Eureka的自我保护阶段,剔除节点延迟
心跳丢失超过90秒后,节点才会被剔除,如果频繁重启服务,建议调小lease-renewal-interval-in-seconds


Eureka服务注册机制的核心就是“注册-心跳-发现-调用”四个动作,通过本文案例,你可以快速搭建起一个具备高可用能力的注册中心,并掌握Provider与Consumer的完整链路,后续可结合Spring Cloud Gateway、Config等组件,构建更完整的微服务生态。注册中心是微服务的第一块基石,做好降级和容错设计永远不嫌早

(本文所有实践代码均可在Spring Boot 2.3.x + Hoxton.SR12版本下直接运行。)

抱歉,评论功能暂时关闭!