2、SpringCloud-Eureka服务注册中心

一、服务注册中心

注意:服务注册中心本质上是为了解耦服务提供者和服务消费者。

对于任何一个微服务,原则上都应存在或者支持多个提供者(比如简历微服务部署 多个实例),这是由微服务的分布式属性决定的。更进一步,为了支持弹性扩缩容特性,一个微服务的提供者的数量和分布往往是动 态变化的,也是无法预先确定的。因此,原本在单体应用阶段常用的静态LB机制就 不再适用了,需要引入额外的组件来管理微服务提供者的注册与发现,而这个组件 就是服务注册中心

二、服务注册中心的一般原理

image-20220310003054118

分布式微服务架构中,服务注册中心用于存储服务提供者地址信息、服务发布相关的属性信息,消费者通过主动查询和被动通知的方式获取服务提供者的地址信息,而不再需要通过硬编码方式得到提供者的地址信息。消费者只需要知道当前系统发布了那些服务,而不需要知道服务具体存在于什么位置,这就是透明化路由

  • 1)服务提供者启动
  • 2)服务提供者将相关服务信息主动注册到注册中心
  • 3)服务消费者获取服务注册信息:
    • pull模式:服务消费者可以主动拉取可用的服务提供者清单
    • push模式:服务消费者订阅服务(当服务提供者有变化时,注册中心也会主动推送 更新后的服务清单给消费者
  • 服务消费者直接调用服务提供者
  • 另外,注册中心也需要完成服务提供者的健康监控,当发现服务提供者失效时需要及时剔除;

三、主流服务中心对比 Zookeeper

3.1Zookeeper

它是一个分布式服务框架,是Apache Hadoop 的一个子项目,它主 要是用来解决分布式应 用中经常遇到的一些数据管理问题,如:统一命名服 务、状态同步服务、集群管理、分布式应用配置项的管理等。

简单来说zookeeper本质=存储+监听通知。

znode

Zookeeper 用来做服务注册中心,主要是因为它具有节点变更通知功能,只要 客户端监听相关服务节点,服务节点的所有变更,都能及时的通知到监听客户 端,这样作为调用方只要使用 Zookeeper 的客户端就能实现服务节点的订阅和 变更通知功能了,非常方便。另外,Zookeeper 可用性也可以,因为只要半数 以上的选举节点存活,整个集群就是可用的。3

3.2 Eureka

由Netflix开源,并被Pivatal集成到SpringCloud体系中,它是基于 RestfulAPI ⻛格开发的服务注册与发现组件。

3.3 Consul

Consul是由HashiCorp基于Go语言开发的支持多数据中心分布式高可用的服务 发布和注册服务软件, 采用Raft算法保证服务的一致性,且支持健康检查。

3.4 Nacos

Nacos是一个更易于构建云原生应用的动态服务发现、配置管理和服务管理平 台。简单来说 Nacos 就是 注册中心 + 配置中心的组合,帮助我们解决微服务开 发必会涉及到的服务注册 与发现,服务配置,服务管理等问题。Nacos 是 Spring Cloud Alibaba 核心组件之一,负责服务注册与发现,还有配置。

四、服务注册中心组件 Eureka

image-20220310013151639

4.1 Eureka 交互流程及原理

image-20220310013209224

Eureka 包含两个组件:Eureka Server 和 Eureka Client,Eureka Client是一个 Java客户端,用于简化与Eureka Server的交互;Eureka Server提供服务发现的 能力,各个微服务启动时,会通过Eureka Client向Eureka Server 进行注册自己 的信息(例如网络信息),Eureka Server会存储该服务的信息

  • 2)图中每一个Eureka Server都是一个集群。

  • 3)图中Application Service作为服务提供者向Eureka Server中注册服务, Eureka Server接受到注册事件会在集群和分区中进行数据同步,Application Client作为消费端(服务消费者)可以从Eureka Server中获取到服务注册信 息,进行服务调用。

  • 4)微服务启动后,会周期性地向Eureka Server发送心跳(默认周期为30秒) 以续约自己的信息

  • 5)Eureka Server在一定时间内没有接收到某个微服务节点的心跳,Eureka Server将会注销该微服务节点(默认90秒)

  • 6)每个Eureka Server同时也是Eureka Client,多个Eureka Server之间通过复 制的方式完成服务注册列表的同步

  • 7)Eureka Client会缓存Eureka Server中的信息。即使所有的Eureka Server节 点都宕掉,服务消费者依然可以使用缓存中的信息找到服务提供者

Eureka通过心跳检测、健康检查和客户端缓存等机制,提高系统的灵活性、可 伸缩性和可用性。

4.2 搭建Eureka Server 服务注册中心

4.2.1 pom工程中加入依赖

<dependencies>
			<!--Eureka server依赖--> <dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-netflix-eureka-server</artifactId>
  </dependency>
</dependencies>

4.2.2 application.yml

#Eureka server服务端口 server:
  port: 8761
spring:
application:
name: lagou-cloud-eureka-server # 应用名称,会在Eureka中作为服务的
id标识(serviceId) eureka:
  instance:
    hostname: localhost
client:
service-url: # 客户端与EurekaServer交互的地址,如果是集群,也需要写其
它Server的地址 defaultZone:
http://${eureka.instance.hostname}:${server.port}/eureka/ register-with-eureka: false # 自己就是服务不需要注册自己 fetch-registry: false #自己就是服务不需要从Eureka Server获取服务信息,默认为true,置为false

4.2.3 SpringBoot启动类,使用@EnableEurekaServer声明当前项目为EurekaServer 服务

@SpringBootApplication
// 声明本项目是一个Eureka服务
@EnableEurekaServer
public class LagouCloudEurekaServerApplication {
    public static void main(String[] args) {
 		SpringApplication.run(LagouCloudEurekaServerApplication.class,args);
	} 
}

4.3 微服务提供者—>注册到Eureka Server集群

4.3.1 父工程中引入spring-cloud-commons依赖

<dependency>
   <groupId>org.springframework.cloud</groupId>
   <artifactId>spring-cloud-commons</artifactId>
 </dependency>

4.3.2 pom文件引入坐标,添加eureka client的相关坐标

<dependency>
   <groupId>org.springframework.cloud</groupId>
   <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
 </dependency>

4.3.3 配置application.yml文件,在application.yml 中添加Eureka Server高可用集群的地址及相关配置

eureka:
  client:
  	serviceUrl: # eureka server的路径 defaultZone:
  http://lagoucloudeurekaservera:8761/eureka/,http://lagoucloudeur ekaserverb:8762/eureka/ #把 eureka 集群中的所有 url 都填写了进来,也 可以只写一台,因为各个 eureka server 可以同步注册表
  instance: #使用ip注册,否则会使用主机名注册了(此处考虑到对老版本的兼容,新版本经
  过实验都是ip)
  	prefer-ip-address: true #自定义实例显示格式,加上版本号,便于多版本管理,注意是ip-address,早
  期版本是ipAddress
  	instance-id: ${spring.cloud.client.ip-
  address}:${spring.application.name}:${server.port}:@project.vers
  ion@

4.3.4 启动类添加注解

@SpringBootApplication
@EnableEurekaClient // 开启Eureka client
//@EnableDiscoveryClient // 开启注册中心客户端 (通用性注解,比如注册到Eureka、Nacos)
public class ServiceResumeApplication {
    public static void main(String[] args) {
        SpringApplication.run(ServiceResumeApplication.class, args);
    }
}
  • 1)从Spring Cloud Edgware版本开始,@EnableDiscoveryClient 或 @EnableEurekaClient 可省略。只需加 上相关依赖,并进行相应配置,即可将 微服务注册到服务发现组件上。

  • 2)@EnableDiscoveryClient和@EnableEurekaClient二者的功能是一样的。但 是如果选用的是eureka服务器,那么就推荐@EnableEurekaClient,如果是其 他的注册中心,那么推荐使用@EnableDiscoveryClient,考虑到通用性,后期 我们可以使用@EnableDiscoveryClient

4.4 微服务消费者—>注册到Eureka Server集群

4.4.1 pom文件引入坐标,添加eureka client的相关坐标

<dependency>
   <groupId>org.springframework.cloud</groupId>
   <artifactId>spring-cloud-commons</artifactId>
 </dependency>
 <dependency>
   <groupId>org.springframework.cloud</groupId>
   <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
 </dependency>

4.4.2 配置application.yml文件

server:
  port: 8090
eureka:
  client:
		serviceUrl: # eureka server的路径 
			defaultZone: http://lagoucloudeurekaservera:8761/eureka/,http://lagoucloudeurekaserverb:8762/eureka/ #把 eureka 集群中的所有 url 都填写了进来,也 可以只写一台,因为各个 eureka server 可以同步注册表
instance: #使用ip注册,否则会使用主机名注册了(此处考虑到对老版本的兼容,新版本经过实验都是ip)
	prefer-ip-address: true #自定义实例显示格式,加上版本号,便于多版本管理,注意是ip-address,早期版本是ipAddress
	instance-id: ${spring.cloud.client.ipaddress}:${spring.application.name}:${server.port}:@project.version@
	 
spring:
  application:
    name: lagou-service-autodeliver

4.4.3 在启动类添加注解@EnableDiscoveryClient,开启服务发现

@SpringBootApplication 
@EnableDiscoveryClient // 开启服务发现 
public class AutodeliverApplication {
    public static void main(String[] args) {
        SpringApplication.run(AutodeliverApplication.class,
args); }
}

5. Eureka细节详解

5.1 Eureka元数据详解

Eureka的元数据有两种:标准元数据和自定义元数据。

  • 标准元数据:主机名、IP地址、端口号等信息,这些信息都会被发布在服务注册表中,用于服务之间的调用。
  • 自定义元数据:可以使用eureka.instance.metadata-map配置,符合KEY/VALUE的 存储格式。这 些元数据可以在远程客户端中访问。

自定义元数据

instance:
    prefer-ip-address: true
    metadata-map:
			# 自定义元数据(kv自定义) 
			cluster: cl1
			region: rn1

image-20220316010850513

5.2 Eureka客户端详解

服务提供者(也是Eureka客户端)要向EurekaServer注册服务,并完成服务续约等工作

5.2.1 服务注册详解(服务提供者)

  • 1)当我们导入了eureka-client依赖坐标,配置Eureka服务注册中心地址
  • 2)服务在启动时会向注册中心发起注册请求,携带服务元数据信息
  • 3)Eureka注册中心会把服务的信息保存在Map中。

5.2.2 服务续约详解(服务提供者)

服务每隔30秒会向注册中心续约(心跳)一次(也称为报活),如果没有续约,租约在 90秒后到期,然后服务会被失效。每隔30秒的续约操作我们称之为心跳检测

5.2.3 调整这两个配置

#向Eureka服务中心集群注册服务 
eureka:
	instance:
		# 租约续约间隔时间,默认30秒 
		lease-renewal-interval-in-seconds: 30
		# 租约到期,服务时效时间,默认值90秒,服务超过90秒没有发生心跳,EurekaServer会将服务从列表移除 
		lease-expiration-duration-in-seconds: 90

5.2.4 获取服务列表详解(服务消费者)

每隔30秒服务会从注册中心中拉取一份服务列表,这个时间可以通过配置修改。

也可以调整配置

#向Eureka服务中心集群注册服务 
eureka:
	client:
		# 每隔多久拉取一次服务列表 
		registry-fetch-interval-seconds: 30
  • 1)服务消费者启动时,从 EurekaServer服务列表获取只读备份,缓存到本地
  • 2)每隔30秒,会重新获取并更新数据
  • 3)每隔30秒的时间可以通过配置eureka.client.registry-fetch-interval-seconds修 改

5.3 Eureka服务端详解

5.3.1 服务下线

  • 1)当服务正常关闭操作时,会发送服务下线的REST请求给EurekaServer。
  • 2)服务中心接受到请求后,将该服务置为下线状态

5.3.2 失效剔除

Eureka Server会定时(间隔值是eureka.server.eviction-interval-timer-in-ms,默 认60s)进行检查,如果发现实例在在一定时间(此值由客户端设置的 eureka.instance.lease-expiration-duration-in-seconds定义,默认值为90s)内没 有收到心跳,则会注销此实例。

5.3.3 自我保护

定期的续约(服务提供者和注册中心通信),假如服务提供者和注册中心之间的网络有点问题,不代表服务提供者不可用,不代表服务消费者无法访问服务提供者 如果在15分钟内超过85%的客户端节点都没有正常的心跳,那么Eureka就认为客户端与注册中心出现了网络故障,Eureka Server自动进入自我保护机制

为什么会有自我保护机制?

默认情况下,如果Eureka Server在一定时间内(默认90秒)没有接收到某个微服务 实例的心跳,Eureka Server将会移除该实例。但是当网络分区故障发生时,微服务 与Eureka Server之间无法正常通信,而微服务本身是正常运行的,此时不应该移除 这个微服务,所以引入了自我保护机制

当处于自我保护模式时
  • 1)不会剔除任何服务实例(可能是服务提供者和EurekaServer之间网络问题),保 证了大多数服务依然可用

  • 2)Eureka Server仍然能够接受新服务的注册和查询请求,但是不会被同步到其它 节点上,保证当前节点依然可用,当网络稳定时,当前Eureka Server新的注册信息 会被同步到其它节点中。

  • 3)在Eureka Server工程中通过eureka.server.enable-self-preservation配置可用 关停自我保护,默认值是打开

eureka:
  server:
		enable-self-preservation: false # 关闭自我保护模式(缺省为打开)

6. Eureka核心源码剖析

6.1 Eureka Server启动过程

  • springboot应用启动时会加载EurekaServerAutoConfiguration自动配置类

    image-20220316011949479

  • 需要有一个marker bean,才能装配Eureka Server,那么这个marker 其实是@EnableEurekaServer注解决定的,也就是说只有添加了@EnableEurekaServer注解,才会有后续的动作,这是成为一 个EurekaServer的前提image-20220316012025435

image-20220316012152793

image-20220316012300295

  • 而在 com.netflix.eureka.cluster.PeerEurekaNodes#start方法中

image-20220316012334601

  • EurekaServerInitializerConfiguration,重点关注,进入 EurekaServerBootstrap#contextInitialized

image-20220316012427685

6.2 Eureka Server服务接口暴露策略

在Eureka Server启动过程中主配置类注册了Jersey框架(是一个发布restful⻛格接口的框架,类似于我们的springmvc)

image-20220316012656841

image-20220316012708841

6.3 Eureka Server服务注册接口(接受客户端注册服务)

  • ApplicationResource类的addInstance()方法中代码:registry.register(info, "true".equals(isReplication));

image-20220316012800688

  • com.netflix.eureka.registry.PeerAwareInstanceRegistryImpl#register - 注册服务 信息并同步到其它Eureka节点

image-20220316012829462

  • AbstractInstanceRegistry#register():注册,实例信息存储到注册表是一个 ConcurrentHashMap

6.4 Eureka Server服务续约接口(接受客户端续约)

  • InstanceResource的renewLease方法中完成客户端的心跳(续约)处理,关键代 码:registry.renew(app.getName(), id, isFromReplicaNode);

6.5 Eureka Client注册服务

启动过程:Eureka客户端在启动时也会装载很多配置类,我们通过spring-cloud- netflix-eureka-client-2.1.0.RELEASE.jar下的spring.factories文件可以看到加载的配 置类

  • EurekaClientAutoConfiguration

image-20220316013033190

  • 1)读取配置文件
  • 2)启动时从EurekaServer获取服务实例信息
  • 3)注册自己到EurekaServer(addInstance)
  • 4)开启一些定时任务(心跳续约,刷新本地服务缓存列表)

6.6 Eureka Client下架服务

com.netflix.discovery.DiscoveryClient#shutdown

image-20220316013159497

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值