Eureka概述
Spring Cloud封装了Netflix 公司开发的Eureka模块来实现服务治理,SpringCloud将它集成在其子项目spring-cloud-netflix中
在服务注册与发现中,有一个注册中心。当服务器启动的时候,会把当前自己服务器的信息比如服务地址通讯地址等以别名方式注册到注册中心上
强调一下,eureka从2.0开源版本已经停止,不再维护,建议使用alibaba的nacos作为注册中新和配置中心
Eureka核心原理
Eureka组件
Eureka Server:Eureka Server提供服务注册服务,各个节点启动后,会在Eureka Server中进行注册
Eureka Client:Eureka Client用于简化与Eureka Server的交互,向注册中心注册、服务续约,下线、拉取注册信息
Eureka Server 和Eureka Client 都需要自己搭建,而nacos不需要自己搭建注册中心服务,各自的微服务中只需集成客户端即可
Eureka Server
Eureka Server提供服务注册服务,各个节点启动后,会在Eureka Server中进行注册,并且注册服务会对注册信息进行缓存
服务注册:服务提供者启动时,会通过 Eureka Client 向 Eureka Server 注册信息,Eureka Server 会存储该服务的信息,Eureka Server 内部有二层缓存机制来维护整个注册表,相当于注册服务会维护一个map来缓存信息
public abstract class AbstractInstanceRegistry implements InstanceRegistry {
private static final Logger logger = LoggerFactory.getLogger(AbstractInstanceRegistry.class);
private static final String[] EMPTY_STR_ARRAY = new String[0];
private final ConcurrentHashMap<String, Map<String, Lease<InstanceInfo>>> registry = new ConcurrentHashMap();
protected Map<String, RemoteRegionRegistry> regionNameVSRemoteRegistry = new HashMap();
protected final ConcurrentMap<String, InstanceStatus> overriddenInstanceStatusMap;
private final AbstractInstanceRegistry.CircularQueue<Pair<Long, String>> recentRegisteredQueue;
private final AbstractInstanceRegistry.CircularQueue<Pair<Long, String>> recentCanceledQueue;
private ConcurrentLinkedQueue<AbstractInstanceRegistry.RecentlyChangedItem> recentlyChangedQueue;
提供注册表:服务消费者在调用服务时,如果 Eureka Client 没有缓存注册表的话,会从 Eureka Server 获取最新的注册表
同步状态:Eureka Client 通过注册、心跳机制和 Eureka Server 同步当前客户端的状态
Eureka Client
在应用启动后,将会向Eureka Server发送心跳,默认周期为30秒,如果Eureka Server在多个心跳周期内没有接收到某个节点的心跳,Eureka Server将会从服务注册表中把这个服务节点移除(默认90秒),Eureka Client 会拉取、更新和缓存 Eureka Server 中的信息
因此当所有的 Eureka Server 节点都宕掉,服务消费者依然可以使用缓存中的信息找到服务提供者,但是当服务有更改的时候会出现信息不一致
服务注册:client在启动的时候将自身注册到注册服务,它提供自身的元数据,比如 IP 地址、端口,运行状况指示符 URL,主页等
服务续约:Eureka Client服务注册后, 会每隔 30 秒发送一次心跳来续约。 通过续约来告知 Eureka Server 该 Eureka Client 运行正常,没有出现问题
服务剔除: Eureka Server启动时会创建一个定时任务,每隔60s执行一次,把当前注册表中超时(90s)没有续约的Eureka Client服务剔除,但实际上是180s剔除,这是Eureka的一个bug
在服务续约的时候将服务的过期时间修改为当前时间加90s,
后台线程检测线程(60s检测一次)判断注册信息是否需要过期剔除的时候,又将过期时间增加了 90s 然后和当前时间校对,相当于一共延后了180s
拉取注册列表:每隔30s 拉取Eureka Server注册实例信息。TimedSupervisorTask 固定周期性任务,一但超时就会将下一个任务的执行时间间隔增大一倍,直到超过最大任务执行间隔的限制,一旦任务不在超时,就会将任务的执行间隔恢复为默认值
服务下线:Eureka Client 在程序关闭时向 Eureka Server 发送取消请求。 发送请求后,该客户端实例信息将从 Eureka Server 的实例注册表中删除
Eureka Server搭建
添加依赖
<dependencies>
<!--eureka服务端-->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-server</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
</dependencies>
添加配置
application.yml
server:
port: 9000
spring:
application:
name: cloud-eureka-server
eureka:
client:
service-url:
defaultZone: http://127.0.0.1:9000/eureka/
register-with-eureka: false
在启动类上添加服务中心注解@EnableEurekaServer
package com.slbuildenv.cloud;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.netflix.eureka.server.EnableEurekaServer;
@SpringBootApplication
@EnableEurekaServer
public class EurekaMainApplication {
public static void main(String[] args) {
SpringApplication.run(EurekaMainApplication.class,args);
}
}
启动访问
Eureka Client搭建
添加依赖
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
</dependency>
</dependencies>
添加配置
application.properties
server.port= 9400
spring.application.name= cloud-test-service
eureka.client.service-url.defaultZone= http://127.0.0.1:9000/eureka
添加客户端注解@EnableEurekaClient
package com.slbuildenv.cloud;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.netflix.eureka.EnableEurekaClient;
@SpringBootApplication
@EnableEurekaClient
public class TestMainApplication {
public static void main(String[] args) {
SpringApplication.run(TestMainApplication.class,args);
}
}
启动测试
可以看到我们的服务已经注册到Eureka Server上
Eureka集群配置
集群配置很简单,这里不做搭建,写一下集群配置如下:
eureka:
client:
register-with-eureka: true
#是否从EurekaServer抓取已有的注册信息,默认为true。单节点无所谓,集群必须设置为true才能配合ribbon使用负载均衡
fetchRegistry: true
service-url:
#集群配置使用逗号隔开即可
defaultZone: http://127.0.0.1:9000/eureka, http://127.0.0.1:9001/eureka