03.2 Eureka自我保护和服务发现

1. 自我保护

1.1 演示

先后启动eureka和provider,provider空置一段时间即可看到。

1.2 故障现象

1.3 导致原因

什么是自我保护模式?

默认情况下,如果EurekaServer在一定时间内没有接收到某个微服务实例的心跳,EurekaServer将会注销该实例(默认90秒)。但是当网络分区故障发生时,微服务与EurekaServer之间无法正常通信,以上行为可能变得非常危险了——因为微服务本身其实是健康的,此时本不应该注销这个微服务。Eureka通过“自我保护模式”来解决这个问题——当EurekaServer节点在短时间内丢失过多客户端时(可能发生了网络分区故障),那么这个节点就会进入自我保护模式。一旦进入该模式,EurekaServer就会保护服务注册表中的信息,不再删除服务注册表中的数据(也就是不会注销任何微服务)。当网络故障恢复后,该Eureka Server节点会自动退出自我保护模式。

在自我保护模式中,Eureka Server会保护服务注册表中的信息,不再注销任何服务实例。当它收到的心跳数重新恢复到阈值以上时,该Eureka Server节点就会自动退出自我保护模式。它的设计哲学就是宁可保留错误的服务注册信息,也不盲目注销任何可能健康的服务实例。一句话讲解:好死不如赖活着

综上,自我保护模式是一种应对网络异常的安全保护措施。它的架构哲学是宁可同时保留所有微服务(健康的微服务和不健康的微服务都会保留),也不盲目注销任何健康的微服务。使用自我保护模式,可以让Eureka集群更加的健壮、稳定。

在Spring Cloud中,可以使用eureka.server.enable-self-preservation = false 禁用自我保护模式。

2.服务发现

对于注册进eureka里面的微服务,可以通过服务发现来获得该服务的信息

2.1 修改microservicecloud-provider-dept-8001工程的DeptController

增加如下代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
@Autowired
private DiscoveryClient client;
@RequestMapping(value = "/dept/discovery", method = RequestMethod.GET)
public Object discovery() {
List<String> list = client.getServices();
System.out.println("**********" + list);

List<ServiceInstance> srvList = client.getInstances("MICROSERVICECLOUD-DEPT");
for (ServiceInstance element : srvList) {
System.out.println(element.getServiceId() + "\t" + element.getHost() + "\t" + element.getPort() + "\t"
+ element.getUri());
}
return this.client;
}

导包注意事项 :
//import com.netflix.discovery.DiscoveryClient;
import org.springframework.cloud.client.ServiceInstance;
import org.springframework.cloud.client.discovery.DiscoveryClient;
要导入springcloud的DiscoveryClient

2.2 DeptProvider8001_App主启动类

1
2
3
4
5
6
7
8
9
10
@SpringBootApplication
// 本服务启动后会自动注册进 eureka 服务中
@EnableEurekaClient
// 服务发现
@EnableDiscoveryClient
public class ProviderDept8001Application {
public static void main(String[] args) {
SpringApplication.run(ProviderDept8001Application.class, args);
}
}

2.3 修改microservicecloud-consumer-dept-80工程的DeptController_Consumer

增加下面代码

1
2
3
4
5
//测试@EnableDiscoveryClient,消费端可以调用服务发现
@RequestMapping(value="/consumer/dept/discovery")
public Object discovery() {
return restTemplate.getForObject(REST_URL_PREFIX+"/dept/discovery", Object.class);
}

2.4 测试

访问URL
http://localhost:8001/dept/discovery
http://localhost/consumer/dept/discovery

资源获取

公众号回复 : Eureka自我保护和服务发现 获取本节代码

公众号回复 : SpringCloud思维导图

Tips

欢迎收藏和转发,感谢你的支持!(๑•̀ㅂ•́)و✧

欢迎关注我:后端小哥,专注后端开发,希望和你一起进步!