Spring Cloud Eureka 是 Netflix 公司开发的注册发现组件,本身是一个基于 REST 的服务。提供注册与发现,同时还提供了负载均衡、故障转移等能力。
Eureka 有 3 个角色
Eureka 是 AP 架构(可用性和分区容错性),Zookeeper 是 CP 架构(一致性和分区容错性)。Eueka 优先保证服务的可用性,Zookeeper 在 Master 节点因为网络故障与其他节点失去联系时,剩余节点选取 leader 的时间太长,这就导致在选举期间注册服务瘫痪。
首先需要创建一个 spring-cloud 工程,删除 src 目录,然后在 pom.xml 文件中加入以下依赖:
<properties>
<project.build.sourceEncoding>UTF-8project.build.sourceEncoding>
<maven.compiler.source>1.8maven.compiler.source>
<maven.compiler.target>1.8maven.compiler.target>
<spring-cloud.version>2021.0.0spring-cloud.version>
<spring-boot.version>2.6.3spring-boot.version>
properties>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.bootgroupId>
<artifactId>spring-boot-starter-parentartifactId>
<version>${spring-boot.version}version>
<type>pomtype>
<scope>importscope>
dependency>
<dependency>
<groupId>org.springframework.cloudgroupId>
<artifactId>spring-cloud-dependenciesartifactId>
<version>${spring-cloud.version}version>
<type>pomtype>
<scope>importscope>
dependency>
dependencies>
dependencyManagement>
创建 eureka-server-7001 模块,然后在 pom.xml 文件中加入以下依赖:
<dependency>
<groupId>org.springframework.cloudgroupId>
<artifactId>spring-cloud-starter-netflix-eureka-serverartifactId>
dependency>
写 application.yaml 配置文件,具体如下:
server:
port: 7001
eureka:
instance:
# eureka服务端的实例名字
hostname: localhost
client:
# 是否将自己注册到eureka server
register-with-eureka: false
# 是否从eureka server获取注册的服务信息
fetch-registry: false
# 设置与eureka server交互的地址
service-url:
defalutZone: http://${eureka.instance.hostname}:${server.port}/eureka/
最后在启动类上加上 @EnableEurekaServer 注解即可
@EnableEurekaServer
启动访问 localhost:7001 即可访问到 Eureka 注册中心的界面。
创建服务提供者 provider-8001 和服务消费者 consumer-80 模块,然后在 pom.xml 文件中加入以下依赖:
<dependency>
<groupId>org.springframework.cloudgroupId>
<artifactId>spring-cloud-starter-netflix-eureka-clientartifactId>
dependency>
<dependency>
<groupId>org.springframework.bootgroupId>
<artifactId>spring-boot-starter-webartifactId>
dependency>
服务提供者和消费者的依赖是一样的,都是 eureka-client。
写 application.yaml 配置文件,具体如下:
server:
port: 8001
spring:
application:
name: cloud-provider-8001
eureka:
client:
# eureka服务地址
service-url:
defaultZone: http://localhost:7001/eureka/
server:
port: 80
spring:
application:
name: cloud-consumer-80
eureka:
client:
service-url:
defaultZone: http://localhost:7001/eureka/
最后在启动类上面加 @EnableEurekaClient 注解即可。
@EnableEurekaClient
先启动 Eureka 注册中心,然后在分别启动服务提供者和服务消费者,即可在 Eureka 服务注册中心看到相关信息。
访问上面我们搭建的注册中心(localhost:7001),界面如下:
其中最重要的是中间服务信息的那一栏,实例的状态有以下几种:
服务自保机制(Service Self-Preservation Mechanism):是指 Eureka Server 中的一种机制,用于保护在 Eureka 注册中心上注册的微服务实例免受意外删除的影响。当微服务实例在心跳超时时间内没有发送心跳信号给 Eureka Server 时,Eureka Server 不会立即将其从服务注册表中删除,而是认为该实例可能处于网络故障等临时异常情况,会将其保留在注册表中,提供一定的自我保护,防止误删健康的实例。这样可以避免因网络抖动、服务器负载或其他临时问题导致服务实例被误删,从而提高服务的稳定性和可用性。
服务剔除机制(Service Eviction Mechanism):与服务自保相对应,是指当服务实例连续长时间未发送心跳信号、或注册中心发现某个服务实例心跳连续失败的次数超过一定阈值时,Eureka Server 会将该服务实例从服务注册表中剔除。通过服务剔除机制,可以排除不健康、异常或故障状态的服务实例,防止其他服务继续调用故障的实例,减少错误的传播范围,提高系统的稳定性。
Eureka 中的服务自保机制是为了保护健康、可能出现临时异常的服务实例免受误删的影响,而服务剔除机制则是为了及时剔除不健康、长时间未发送心跳或心跳连续失败的服务实例,保障整个服务治理系统的正常运行。这两个机制的存在都是为了提高服务的可靠性和稳定性。
服务自保是默认开启的,可以使用以下配置来关闭,在 Eureka Server 的 application.yaml 配置文件中加入以下配置:
eureka:
server:
# 参数来关闭保护机制,已确保注册中心可以将不可用的实例正确剔除,默认为true
enable-self-preservation: false
SpringCloud 体系里的服务实体向 Eureka 注册时,注册名默认是 IP名:应用名:应用端口名。
我们可以通过 actuator 来修改完善注册名,在服务提供者或消费者的 pom.xml 文件中加入以下配置:
<dependency>
<groupId>org.springframework.bootgroupId>
<artifactId>spring-boot-starter-actuatorartifactId>
dependency>
然后在 application.yaml 配置文件中加入以下配置:
eureka:
instance:
# 实例名称
instance-id: cloud-consumer01-80
注册进入 Eureka 里面的微服务,可以通过服务发现来获取该服务的信息。
在服务提供者模块controller类,具体如下:
@Slf4j
@RestController
@RequestMapping("/provider")
public class ProviderController {
@Autowired
private DiscoveryClient discoveryClient;
@GetMapping("/discovery")
public Object discovery() {
// 获取所有微服务信息
List<String> services = discoveryClient.getServices();
for (String service : services) {
log.info("service:={}", service);
}
return this.discoveryClient;
}
/**
* 供消费者调用
*/
@GetMapping("/index")
public String getMsg() {
return "success";
}
}
RestTemplate 是从 Spring3.0 开始支持的一个 HTTP 请求工具,它提供了常见的REST请求方案的模版,例如 GET 请求、POST 请求、PUT 请求、DELETE 请求以及一些通用的请求执行方法 exchange() 以及 execute()。
在服务消费者模块中添加配置类,具体如下:
@Configuration
public class CloudConfig {
@LoadBalanced
@Bean
public RestTemplate restTemplate() {
return new RestTemplate();
}
}
最后在服务消费者模块添加对应调用方法,具体如下:
@RestController
@RequestMapping("/consumer")
public class ConsumerController {
@Autowired
private RestTemplate restTemplate;
@GetMapping("/index")
public String index() {
// 远程微服务调用地址: 微服务名称
String host = "http://cloud-provider-8001";
// 具体URL
String url = "/provider/index";
// 发起远程调用
// getForObject: 返回响应体中数据转化成的对象, 可以理解为json
// getForEntity: 返回的是ResponseEntity的对象包含了一些重要的信息
return restTemplate.getForObject(host + url, String.class);
}
}
浏览器访问:http://localhost:80/consumer/index 地址,即出现在服务提供者模块中返回的 “success” 字符串。