1,概述
Eureka 是 Netflix 公司开发的一款开源的服务注册与发现组件。
Eureka 是 Spring Cloud Netflix 模块的子模块,它是 Spring Cloud 对 Netflix Eureka 的二次封装,主要负责 Spring Cloud 的服务注册与发现功能。
Eureka 两大组件
Eureka 采用 CS(Client/Server,客户端/服务器) 架构,它包括以下两大组件:
- Eureka Server:Eureka 服务注册中心,主要用于提供服务注册功能。当微服务启动时,会将自己的服务注册到 Eureka Server。Eureka Server 维护了一个可用服务列表,存储了所有注册到 Eureka Server 的可用服务的信息,这些可用服务可以在 Eureka Server 的管理界面中直观看到。
- Eureka Client:Eureka 客户端,通常指的是微服务系统中各个微服务,主要用于和 Eureka Server 进行交互。在微服务应用启动后,Eureka Client 会向 Eureka Server 发送心跳(默认周期为 30 秒)。若 Eureka Server 在多个心跳周期内没有接收到某个 Eureka Client 的心跳,Eureka Server 将它从可用服务列表中移除(默认 90 秒)。
Eureka原理图
服务注册中心(Register Service):它是一个 Eureka Server,用于提供服务注册和发现功能。
服务提供者(Provider Service):它是一个 Eureka Client,用于提供服务。它将自己提供的服务注册到服务注册中心,以供服务消费者发现。
服务消费者(Consumer Service):它是一个 Eureka Client,用于消费服务。它可以从服务注册中心获取服务列表,调用所需的服务。
Eureka 实现服务注册与发现的流程如下:
- 搭建一个 Eureka Server 作为服务注册中心;
- 服务提供者 Eureka Client 启动时,会把当前服务器的信息以服务名(spring.application.name)的方式注册到服务注册中心;
- 服务消费者 Eureka Client 启动时,也会向服务注册中心注册;
- 服务消费者还会获取一份可用服务列表,该列表中包含了所有注册到服务注册中心的服务信息(包括服务提供者和自身的信息);
- 在获得了可用服务列表后,服务消费者通过 HTTP 或消息中间件远程调用服务提供者提供的服务。
服务注册中心(Eureka Server)所扮演的角色十分重要,它是服务提供者和服务消费者之间的桥梁。服务提供者只有将自己的服务注册到服务注册中心才可能被服务消费者调用,而服务消费者也只有通过服务注册中心获取可用服务列表后,才能调用所需的服务。
2,示例
maven项目创建 依赖导入
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
</dependency>
application.yaml配置文件配置
server:
port: 10086
spring:
application:
name: eureka-server
#Eureka配置 先自己配置自己 保证不报错
eureka:
client:
service-url:
defaultZone: http://localhost:10086/eureka
SpringBoot启动类编写
@SpringBootApplication
@EnableEurekaServer
public class EurekaServerApplication {
public static void main(String[] args) {
SpringApplication.run(EurekaServerApplication.class,args);
}
}
项目启动 将服务注册到注册列表中
3,从注册中心拉取服务使用
//DiscoveryClient 可以从注册中心获取可用的服务实例列表,供本地服务调用。
@Autowired
private DiscoveryClient discoveryClient;
@GetMapping("/{id}")
public Order getById(@PathVariable Long id){
Order order = this.orderService.getById(id);
//Eureka注册中心拉取 user-service 服务 获取集合
List<ServiceInstance> serviceInstanceList = discoveryClient.getInstances("user-service");
//获取集合中索引为0的服务
ServiceInstance serviceInstance = serviceInstanceList.get(0);
System.out.println("serviceInstance = " + serviceInstance);
//动态拼接url请求地址
String url = "http://"+serviceInstance.getHost()+":"+serviceInstance.getPort();
User user = restTemplate.getForObject(url+"/user/" + order.getUserId(), User.class);
order.setUser(user);
return order;
}
4,搭建Eureka集群
右键copy服务
设置端口,以及服务名称
copy完成三个Eureka服务
10086中原服务配置文件中配置
#Eureka配置 先自己配置自己 保证不报错
eureka:
client:
service-url:
defaultZone: http://localhost:10086/eureka,http://localhost:10087/eureka,http://localhost:10088/eureka
copy三个服务,配置好名称与不重复端口,进行启动
浏览器访问Eureka端口,进行注册中心查看服务。
理想状态下挂掉一台 Erueka 对于整个项目是没有影响的,并且彼此之间的数据是共享的,这样就形成了集群。
5,失效剔除与自我保护
失效剔除
Eureka Server
在启动完成后会创建一个定时器每隔60秒
检查一次服务健康状况
,如果其中一个服务节点超过90秒
未检查到心跳,那么Eureka Server
会自动从服务实例列表
内将该服务剔除
。由于非正常关闭不会执行
主动下线
动作,所以才会出现失效剔除
机制,该机制主要是应对非正常关闭服务的情况,如:内存溢出
、杀死进程
、服务器宕机
等非正常流程
关闭服务节点时。
自我保护机制
某时刻某个微服务不可以用了,eureka不会立刻清理,依旧会对该微服务的信息进行保存!
默认情况下,如果EurekaServer在一定时间内没有接收到某个微服务实例的心跳,EurekaServer将会注销该实例(默认90秒)。但是当网络分区故障发生时,微服务与Eureka之间无法正常通行,以上行为可能变得非常危险了–因为微服务本身其实是健康的,此时本不应该注销这个服务。
Eureka通过自我保护机制来解决这个问题–当EurekaServer节点在短时间内丢失过多客户端时(可能发生了网络分区故障),那么这个节点就会进入自我保护模式。一旦进入该模式,EurekaServer就会保护服务注册表中的信息,不再删除服务注册表中的数据(也就是不会注销任何微服务)。当网络故障恢复后,该EurekaServer节点会自动退出自我保护模式。
在自我保护模式中,EurekaServer会保护服务注册表中的信息,不再注销任何服务实例。当它收到的心跳数重新恢复到阈值以上时,该EurekaServer节点就会自动退出自我保护模式。它的设计哲学就是宁可保留错误的服务注册信息,也不盲目注销任何可能健康的服务实例。一句话:好死不如赖活着。
自我保护模式是一种应对网络异常的安全保护措施。它的架构哲学是宁可同时保留所有微服务(健康的微服务和不健康的微服务都会保留),也不盲目注销任何健康的微服务。使用自我保护模式,可以让Eureka集群更加的健壮和稳定。
我们可以在SpringBoot项目中配置
eureka:
server:
enable-self-preservation: false # 关闭自我保护模式(缺省为打开)
eviction-interval-timer-in-ms: 1000 # 扫描失效服务的间隔时间(缺省为60*1000ms)
6,Ribbon
Spring Cloud Ribbon是基于Netflix Ribbon实现的一套 客户端 负载均衡工具。
工作原理:
所有的项目都会注册到 Eureka 中,Eureka 允许不同项目的 spring.application.name 相同。当相同时会认为是这些项目是一个集群,所以同一个项目部署多次都是设置应用程序名相同。
Application Client 会从 Eureka 中根据 spring.application.name 加载 Application Service 的列表。根据设定的负载均衡算法,从列表中取出一个 URL,到此 Ribbon 的事情结束。剩下的事情由程序员自己进行技术选型,选择一个 HTTP 协议工具,通过这个 URL 调用 Application Service。
1,导入依赖
这个eureka依赖中集成了ribbon依赖
<!--eurekak客户端依赖-->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-server</artifactId>
</dependency>
2,开启负载均衡注解
@SpringBootApplication
@EnableEurekaClient//添加Eureka注解
public class OrderServiceApplication {
public static void main(String[] args) {
SpringApplication.run(OrderServiceApplication.class,args);
}
@Bean
@LoadBalanced//开启负载均衡
public RestTemplate restTemplate(){
return new RestTemplate();
}
}
3,配置文件配置application.yaml
配置负载均衡策略 随机
user-service:
ribbon:
NFLoadBalancerRuleClassName: com.netflix.loadbalancer.RandomRule
4,copy三个UserService服务 注册到注册中心 配置相同名称 不同端口 让他们成为一个集群。
5,使用集群,随机使用服务
@GetMapping("/{id}")
public Order getById(@PathVariable Long id){
Order order = this.orderService.getById(id);
/**
* http://user-service/user/ 其中user-service为动态表填写的应用名称
* 会从注册中心拉取该名称的列表 为一个集合 会走负载策略 轮询等 访问不同服务
*/
User user = restTemplate.getForObject("http://user-service/user/" + order.getUserId(), User.class);
order.setUser(user);
return order;
}