在微服务架构中,服务的数量往往众多且不断变化。服务之间需要相互调用,而如何让服务之间能够动态地发现彼此就成为了一个关键问题。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: 8761
eureka:
client:
register-with-eureka: false # 不将自己注册到 Eureka Server
fetch-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
@EnableEurekaServer
public 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: 8081
spring:
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
@EnableEurekaClient
public 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;
@RestController
public 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: 8082
spring:
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
@EnableEurekaClient
public 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;
@RestController
public class ConsumerController {
@Autowired
private 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 为微服务架构提供了强大的服务管理能力,使得服务之间的协作更加灵活和高效。