
在微服务架构中,服务的数量往往众多且不断变化。服务之间需要相互调用,而如何让服务之间能够动态地发现彼此就成为了一个关键问题。Spring Cloud Eureka 作为一个服务注册与发现组件,为我们提供了很好的解决方案。它允许服务将自己注册到 Eureka 服务器(服务注册中心),并且能够从注册中心获取其他服务的信息,从而实现服务间的调用。
Eureka 采用了 C-S(客户端 - 服务器)架构。主要包含两个角色:
可以使用 Spring Initializr(https://start.spring.io/)创建一个新的 Spring Boot 项目,添加以下依赖:
<dependencies><dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-starter-netflix-eureka-server</artifactId></dependency></dependencies>
在 application.properties 或 application.yml 中进行配置,以下是 application.yml 的示例:
server:port: 8761eureka:client:register-with-eureka: false # 不将自己注册到 Eureka Serverfetch-registry: false # 不从 Eureka Server 获取服务注册信息server:wait-time-in-ms-when-sync-empty: 0 # 等待同步的时间,设置为 0 立即同步
在主应用类上添加 @EnableEurekaServer 注解:
import org.springframework.boot.SpringApplication;import org.springframework.boot.autoconfigure.SpringBootApplication;import org.springframework.cloud.netflix.eureka.server.EnableEurekaServer;@SpringBootApplication@EnableEurekaServerpublic class EurekaServerApplication {public static void main(String[] args) {SpringApplication.run(EurekaServerApplication.class, args);}}
运行主应用类,访问 http://localhost:8761,可以看到 Eureka Server 的管理界面,此时还没有服务注册。
同样使用 Spring Initializr 创建一个新的 Spring Boot 项目,添加以下依赖:
<dependencies><dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-starter-netflix-eureka-client</artifactId></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId></dependency></dependencies>
在 application.yml 中进行配置:
server:port: 8081spring:application:name: service-provider # 服务名eureka:client:service-url:defaultZone: http://localhost:8761/eureka/ # Eureka Server 的地址
在主应用类上添加 @EnableEurekaClient 注解:
import org.springframework.boot.SpringApplication;import org.springframework.boot.autoconfigure.SpringBootApplication;import org.springframework.cloud.netflix.eureka.client.EnableEurekaClient;@SpringBootApplication@EnableEurekaClientpublic class ServiceProviderApplication {public static void main(String[] args) {SpringApplication.run(ServiceProviderApplication.class, args);}}
创建一个简单的 RESTful 接口:
import org.springframework.web.bind.annotation.GetMapping;import org.springframework.web.bind.annotation.RestController;@RestControllerpublic class HelloController {@GetMapping("/hello")public String hello() {return "Hello from service provider!";}}
运行主应用类,再次访问 http://localhost:8761,可以看到 service-provider 服务已经注册到 Eureka Server。
使用 Spring Initializr 创建一个新的 Spring Boot 项目,添加以下依赖:
<dependencies><dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-starter-netflix-eureka-client</artifactId></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId></dependency></dependencies>
在 application.yml 中进行配置:
server:port: 8082spring:application:name: service-consumer # 服务名eureka:client:service-url:defaultZone: http://localhost:8761/eureka/ # Eureka Server 的地址
在主应用类上添加 @EnableEurekaClient 注解:
import org.springframework.boot.SpringApplication;import org.springframework.boot.autoconfigure.SpringBootApplication;import org.springframework.cloud.netflix.eureka.client.EnableEurekaClient;@SpringBootApplication@EnableEurekaClientpublic class ServiceConsumerApplication {public static void main(String[] args) {SpringApplication.run(ServiceConsumerApplication.class, args);}}
使用 RestTemplate 调用服务提供者的接口:
import org.springframework.beans.factory.annotation.Autowired;import org.springframework.cloud.client.ServiceInstance;import org.springframework.cloud.client.discovery.DiscoveryClient;import org.springframework.web.bind.annotation.GetMapping;import org.springframework.web.bind.annotation.RestController;import org.springframework.web.client.RestTemplate;import java.util.List;@RestControllerpublic class ConsumerController {@Autowiredprivate DiscoveryClient discoveryClient;@GetMapping("/call")public String callService() {// 获取服务提供者的实例列表List<ServiceInstance> instances = discoveryClient.getInstances("service-provider");if (instances!= null &&!instances.isEmpty()) {ServiceInstance instance = instances.get(0);String url = "http://" + instance.getHost() + ":" + instance.getPort() + "/hello";RestTemplate restTemplate = new RestTemplate();return restTemplate.getForObject(url, String.class);}return "Service not available";}}
运行主应用类,访问 http://localhost:8082/call,可以看到服务提供者返回的信息。
| 角色 | 作用 | 关键配置 | 注解 |
|---|---|---|---|
| Eureka Server | 服务注册中心,管理服务注册信息 | register-with-eureka: false,fetch-registry: false |
@EnableEurekaServer |
| 服务提供者 | 向 Eureka Server 注册服务 | spring.application.name,eureka.client.service-url.defaultZone |
@EnableEurekaClient |
| 服务消费者 | 从 Eureka Server 获取服务信息并调用 | spring.application.name,eureka.client.service-url.defaultZone |
@EnableEurekaClient |
通过以上步骤,我们成功搭建了一个基于 Eureka 的服务注册与发现系统,实现了服务的动态注册和调用。Eureka 为微服务架构提供了强大的服务管理能力,使得服务之间的协作更加灵活和高效。