微信登录

服务注册与发现 - Eureka - 服务注册中心

Java - Web - Spring 《服务注册与发现 - Eureka - 服务注册中心》

一、引言

在微服务架构中,服务的数量往往众多且不断变化。服务之间需要相互调用,而如何让服务之间能够动态地发现彼此就成为了一个关键问题。Spring Cloud Eureka 作为一个服务注册与发现组件,为我们提供了很好的解决方案。它允许服务将自己注册到 Eureka 服务器(服务注册中心),并且能够从注册中心获取其他服务的信息,从而实现服务间的调用。

二、Eureka 原理

Eureka 采用了 C-S(客户端 - 服务器)架构。主要包含两个角色:

  1. Eureka Server(服务注册中心):作为服务的管理者,接收服务的注册信息,并维护这些信息。同时,它还提供了服务信息的查询接口,供其他服务发现使用。
  2. Eureka Client(服务提供者和消费者):服务提供者将自己的服务信息(如服务名、IP 地址、端口等)注册到 Eureka Server;服务消费者从 Eureka Server 获取其他服务的信息,以便进行服务调用。

工作流程

  • 服务注册:服务提供者启动时,向 Eureka Server 发送注册请求,将自己的信息注册到注册中心。
  • 服务续约:服务提供者每隔一段时间(默认 30 秒)向 Eureka Server 发送心跳请求,表明自己仍然可用。
  • 服务剔除:如果 Eureka Server 在一定时间(默认 90 秒)内没有收到服务提供者的心跳,就会将该服务从注册列表中剔除。
  • 服务发现:服务消费者启动时,从 Eureka Server 获取服务注册列表,并缓存到本地。之后,服务消费者可以根据缓存的信息调用其他服务。

三、搭建 Eureka 服务注册中心

1. 创建 Spring Boot 项目

可以使用 Spring Initializr(https://start.spring.io/)创建一个新的 Spring Boot 项目,添加以下依赖:

  1. <dependencies>
  2. <dependency>
  3. <groupId>org.springframework.cloud</groupId>
  4. <artifactId>spring-cloud-starter-netflix-eureka-server</artifactId>
  5. </dependency>
  6. </dependencies>

2. 配置 Eureka Server

application.propertiesapplication.yml 中进行配置,以下是 application.yml 的示例:

  1. server:
  2. port: 8761
  3. eureka:
  4. client:
  5. register-with-eureka: false # 不将自己注册到 Eureka Server
  6. fetch-registry: false # 不从 Eureka Server 获取服务注册信息
  7. server:
  8. wait-time-in-ms-when-sync-empty: 0 # 等待同步的时间,设置为 0 立即同步

3. 启用 Eureka Server

在主应用类上添加 @EnableEurekaServer 注解:

  1. import org.springframework.boot.SpringApplication;
  2. import org.springframework.boot.autoconfigure.SpringBootApplication;
  3. import org.springframework.cloud.netflix.eureka.server.EnableEurekaServer;
  4. @SpringBootApplication
  5. @EnableEurekaServer
  6. public class EurekaServerApplication {
  7. public static void main(String[] args) {
  8. SpringApplication.run(EurekaServerApplication.class, args);
  9. }
  10. }

4. 启动 Eureka Server

运行主应用类,访问 http://localhost:8761,可以看到 Eureka Server 的管理界面,此时还没有服务注册。

四、服务提供者注册到 Eureka Server

1. 创建服务提供者项目

同样使用 Spring Initializr 创建一个新的 Spring Boot 项目,添加以下依赖:

  1. <dependencies>
  2. <dependency>
  3. <groupId>org.springframework.cloud</groupId>
  4. <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
  5. </dependency>
  6. <dependency>
  7. <groupId>org.springframework.boot</groupId>
  8. <artifactId>spring-boot-starter-web</artifactId>
  9. </dependency>
  10. </dependencies>

2. 配置服务提供者

application.yml 中进行配置:

  1. server:
  2. port: 8081
  3. spring:
  4. application:
  5. name: service-provider # 服务名
  6. eureka:
  7. client:
  8. service-url:
  9. defaultZone: http://localhost:8761/eureka/ # Eureka Server 的地址

3. 启用 Eureka Client

在主应用类上添加 @EnableEurekaClient 注解:

  1. import org.springframework.boot.SpringApplication;
  2. import org.springframework.boot.autoconfigure.SpringBootApplication;
  3. import org.springframework.cloud.netflix.eureka.client.EnableEurekaClient;
  4. @SpringBootApplication
  5. @EnableEurekaClient
  6. public class ServiceProviderApplication {
  7. public static void main(String[] args) {
  8. SpringApplication.run(ServiceProviderApplication.class, args);
  9. }
  10. }

4. 创建服务接口

创建一个简单的 RESTful 接口:

  1. import org.springframework.web.bind.annotation.GetMapping;
  2. import org.springframework.web.bind.annotation.RestController;
  3. @RestController
  4. public class HelloController {
  5. @GetMapping("/hello")
  6. public String hello() {
  7. return "Hello from service provider!";
  8. }
  9. }

5. 启动服务提供者

运行主应用类,再次访问 http://localhost:8761,可以看到 service-provider 服务已经注册到 Eureka Server。

五、服务消费者从 Eureka Server 获取服务信息并调用

1. 创建服务消费者项目

使用 Spring Initializr 创建一个新的 Spring Boot 项目,添加以下依赖:

  1. <dependencies>
  2. <dependency>
  3. <groupId>org.springframework.cloud</groupId>
  4. <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
  5. </dependency>
  6. <dependency>
  7. <groupId>org.springframework.boot</groupId>
  8. <artifactId>spring-boot-starter-web</artifactId>
  9. </dependency>
  10. </dependencies>

2. 配置服务消费者

application.yml 中进行配置:

  1. server:
  2. port: 8082
  3. spring:
  4. application:
  5. name: service-consumer # 服务名
  6. eureka:
  7. client:
  8. service-url:
  9. defaultZone: http://localhost:8761/eureka/ # Eureka Server 的地址

3. 启用 Eureka Client

在主应用类上添加 @EnableEurekaClient 注解:

  1. import org.springframework.boot.SpringApplication;
  2. import org.springframework.boot.autoconfigure.SpringBootApplication;
  3. import org.springframework.cloud.netflix.eureka.client.EnableEurekaClient;
  4. @SpringBootApplication
  5. @EnableEurekaClient
  6. public class ServiceConsumerApplication {
  7. public static void main(String[] args) {
  8. SpringApplication.run(ServiceConsumerApplication.class, args);
  9. }
  10. }

4. 创建服务调用代码

使用 RestTemplate 调用服务提供者的接口:

  1. import org.springframework.beans.factory.annotation.Autowired;
  2. import org.springframework.cloud.client.ServiceInstance;
  3. import org.springframework.cloud.client.discovery.DiscoveryClient;
  4. import org.springframework.web.bind.annotation.GetMapping;
  5. import org.springframework.web.bind.annotation.RestController;
  6. import org.springframework.web.client.RestTemplate;
  7. import java.util.List;
  8. @RestController
  9. public class ConsumerController {
  10. @Autowired
  11. private DiscoveryClient discoveryClient;
  12. @GetMapping("/call")
  13. public String callService() {
  14. // 获取服务提供者的实例列表
  15. List<ServiceInstance> instances = discoveryClient.getInstances("service-provider");
  16. if (instances!= null &&!instances.isEmpty()) {
  17. ServiceInstance instance = instances.get(0);
  18. String url = "http://" + instance.getHost() + ":" + instance.getPort() + "/hello";
  19. RestTemplate restTemplate = new RestTemplate();
  20. return restTemplate.getForObject(url, String.class);
  21. }
  22. return "Service not available";
  23. }
  24. }

5. 启动服务消费者

运行主应用类,访问 http://localhost:8082/call,可以看到服务提供者返回的信息。

六、总结

角色 作用 关键配置 注解
Eureka Server 服务注册中心,管理服务注册信息 register-with-eureka: falsefetch-registry: false @EnableEurekaServer
服务提供者 向 Eureka Server 注册服务 spring.application.nameeureka.client.service-url.defaultZone @EnableEurekaClient
服务消费者 从 Eureka Server 获取服务信息并调用 spring.application.nameeureka.client.service-url.defaultZone @EnableEurekaClient

通过以上步骤,我们成功搭建了一个基于 Eureka 的服务注册与发现系统,实现了服务的动态注册和调用。Eureka 为微服务架构提供了强大的服务管理能力,使得服务之间的协作更加灵活和高效。