天天看点

SpringCloud-Eureka(注册中心)

什么是服务治理?

SpringCloud封装了Eureka模块来实现服务治理,并且遵循的是CAP理论中的AP原则,主管服务的注册与发现

在传统的RPC远程调用框架中,管理每个服务与服务之间依赖关系比较复杂,管理比较复杂,所以需要使用服务治理,管理服务于服务之间依赖关系,可以实现服务调用、负载均衡、容错等,实现服务发现与注册。

什么是服务注册与发现?

Eureka Sever 作为服务注册功能的服务器,它是服务注册中心。

而系统中的其他微服务,使用Eureka的客户端连接到 Eureka Server并维持心跳连接。这样就可以通过Eureka Server来监控系统中各个微服务是否正常运行。

在服务注册与发现中,有一个注册中心。当服务器启动的时候,会把当前自己服务器的信息比如服务地址通讯地址等以别名方式注册到注册中心上。另一方(消费者服务提供者),以该别名的方式去注册中心上获取到实际的服务通讯地址,然后再实现本地RPC调用RPC远程调用框架核心设计思想:在于注册中心,因为使用注册中心管理每个服务与服务之间的一个依赖关系(服务治理概念)。在任何RPC远程框架中,都会有一个注册中心存放服务地址相关信息(接口地址)

SpringCloud-Eureka(注册中心)
  • Eureka Server:提供服务注册和发现
  • Service Provider:服务提供方-----将自身服务注册到Eureka,从而使服务消费方能够找到
  • Service Consumer:服务消费方-----从Eureka获取注册服务列表,从而能够消费服务

Eureka包含两个组件:Eureka Server 和 Eureka Client

  • Eureka Server提供微服务注册服务,在各节点启动后,会在Eureka Server中进行注册,这样Eureka Server中的服务注册表中将会存储所有可用的服务节点信息,服务节点信息可以在界面中直观的看到
  • Eureka Client是一个Java客户端,用于简化Eureka Server的交互,客户端同时也具备一个内置的、使用轮询(round-robin)负载算法的负载均衡器,在应用启动后,将会向Eureka Server发送心跳(默认周期为30秒)。如果Eureka Server在多个心跳周期内没有接收到某个节点的心跳,Eureka Server将会从服务注册表中把这个服务节点移除(默认90秒)

代码开发

代码结构图

SpringCloud-Eureka(注册中心)

大概流程:

  1. 先启动eureka注册中心
  2. 启动服务提供者payment支付服务
  3. 支付服务启动后会把自身的信息(比如服务地址以别名方式注册进eureka)
  4. 消费者order服务在需要调用接口时,使用服务别名去注册中心获取实际的RPC远程调用地址
  5. 消费者获取调用地址后,底层实际是利用HttpClient技术去实现远程调用
  6. 消费者获的服务地址后会缓存在本地jvm内存中,默认每间隔30秒更新一次服务调用地址

服务注册:将服务信息注册进注册中心

服务发现:从注册中心上获取服务信息

实质:存key服务名,取value调用地址

server7001属于Eureka Server,作为注册中心,接受其他微服务注册进来

@SpringBootApplication
@EnableEurekaServer //该注解表示当前的微服务就是Eureka的Server端,注册中心,接受其他微服务注册进来
public class EurekaMain7001 {
    public static void main(String[] args) {
        SpringApplication.run(EurekaMain7001.class,args);
    }

}
           

order80属于消费端,payment8001属于服务提供者,但同时都属于Eureka Client,所以我们在微服务的主启动类上需要添加相对应的注解(前提需要引入相对应的依赖)

  • order80
@SpringBootApplication
@EnableEurekaClient//该注解表示此微服务是一个Eureka客户端,需要注册到Eureka Server(注册中心的)
public class OrderMain80 {
    public static void main(String[] args) {
        SpringApplication.run(OrderMain80.class, args);
    }
}
           
  • payment8001
@SpringBootApplication
@EnableEurekaClient//该注解表示此微服务是一个Eureka客户端,需要注册到Eureka Server(注册中心的)
public class PaymentMain8001 {
    public static void main(String[] args) {
        SpringApplication.run(PaymentMain8001.class, args);
    }
}

           

这里采用application.properties配置方式

#该服务的端口号
server.port=8001

#微服务的名称,注册进Eureka时候,此名称则是该微服务的一个标识,界面上默认是大写的
spring.application.name=cloud-payment-service

#表示是否将自己注册进Eureka Server默认为true。
eureka.client.register-with-eureka=true

#是否从EurekaServer抓取已有的注册信息,默认为true。单节点无所谓,集群必须设置为true才能配合ribbon使用负载均衡
eureka.client.fetch-registry=true

#注册到Eureka Server的时候,需要知道Server所在的地址,才能够注册进去
eureka.client.serviceUrl.defaultZone = http://localhost:7001/eureka/

#使用ip注册,Eureka Server界面的访问地址可以显示IP
eureka.instance.prefer-ip-address = true
#自定义Eureka Server界面的访问地址的显示内容 ip+端口
eureka.instance.instance-id=${spring.cloud.client.ip-address}:${server.port}
           

以上则为一个简单的入门小Demo

微服务RPC远程服务调用最核心的是什么?

高可用,如果注册中心只有一个,它出故障了,会导致整个为服务环境不可用。

解决办法:搭建Eureka注册中心集群,实现负载均衡+故障容错。

Eureka集群

SpringCloud-Eureka(注册中心)

注册中心集群搭建

SpringCloud-Eureka(注册中心)

我们只需要将server7001(Eureka Server)复制一份改名为server7002,就可以搭建两台注册中心了,依次类推,可以搭建多台

修改application.properties配置文件

#服务端口号
server.port=7002

#做集群,eureka服务端的实例名称
eureka.instance.hostname=eureka7002.com

#false表示不向注册中心注册自己,注册中心(服务端)其实并不需要将自己也注册进去
eureka.client.register-with-eureka=false

#false表示自己端就是注册中心,我的职责就是维护服务实例,并不需要去检索服务
eureka.client.fetch-registry=false


#设置与Eureka server交互的地址查询服务和注册服务都需要依赖这个地址。
# 单机就是指向自己,7001自己
# eureka.client.serviceUrl.defaultZone = http://${eureka.instance.hostname}:${server.port}/eureka/

#集群指向其他eureka,可以逗号分割
eureka.client.serviceUrl.defaultZone = http://eurekatest7001.com:7001/eureka/
           
  • eureka.client.serviceUrl.defaultZone说明 单机版的话,后面的url就可以指向自己,但是集群的话就必须要指向其他的所有的注册中心

登录Eureka监控界面查看,可以看到,7001和7002相互注册成为注册中心集群

SpringCloud-Eureka(注册中心)
SpringCloud-Eureka(注册中心)

多个微服务

SpringCloud-Eureka(注册中心)
  • 对于注册中心来说可以搭建集群,防止单点故障,其实对于微服务来说也需要有多个节点
  • 多节点的微服务可以让请求分发到不同的服务器上,也可以防止单点故障

同样的将payment8001复制一份,作为多节点的微服务提供者

修改application.properties配置文件,分别注册到不同的注册中心上

server.port=8002

#微服务的名称,注册进Eureka时候,此名称则是该微服务的一个标识,界面上默认是大写的,如果是集群的话,
#此服务名称必须相同,
spring.application.name=cloud-payment-service

#表示是否将自己注册进Eureka Server默认为true。
eureka.client.register-with-eureka=true

#是否从EurekaServer抓取已有的注册信息,默认为true。单节点无所谓,集群必须设置为true才能配合ribbon使用负载均衡
eureka.client.fetch-registry=true

#注册到Eureka Server的时候,需要知道Server所在的地址,才能够注册进去
# 单机版
# eureka.client.serviceUrl.defaultZone = http://localhost:7001/eureka/
# 集群版配置
eureka.client.serviceUrl.defaultZone=http://eurekatest7002.com:7002/eureka/,http://eurekatest7001.com:7001/eureka/

#使用ip注册,Eureka Server界面的访问地址可以显示IP
eureka.instance.prefer-ip-address = true
eureka.instance.instance-id=${spring.cloud.client.ip-address}:${server.port}
           
SpringCloud-Eureka(注册中心)

服务发现(Discovery)

功能:对于注册进eureka里面的微服务,可以通过服务发现来获得该服务的信息(地址,IP等)

用法:

  • 在Eureka Client 的主启动类上加@EnableDiscoveryClient注解
@SpringBootApplication
@EnableEurekaClient
@EnableDiscoveryClient//开启服务发现,获取服务实例的基础信息
public class PaymentMain8001 {
    public static void main(String[] args) {
        SpringApplication.run(PaymentMain8001.class, args);
    }
}
           

Eureka自我保护理论知识

如果你发现eureka界面显示了下面的这副内容,则说明Eureka进入了保护模式

SpringCloud-Eureka(注册中心)

什么是保护模式?

保护模式主要用于一组Eureka Client 和 Eureka Server之间存在网络分区场景下的保护。一旦进入保护模式,EurekaServer将会尝试保护其服务注册表中的信息,不再删除服务注册表中的数据,也就是不会注销任何微服务。

一句话:某时刻某一个微服务不可用了,Eureka Server不会立刻清理,依旧会对该微服务的信息进行保存。

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

自我保护机制∶默认情况下EurekaClient定时向EurekaServer端发送心跳包

如果Eureka在server端在一定时间内(默认90秒)没有收到Eureka Client发送心跳包,便会直接从服务注册列表中剔除该服务,但是在短时间( 90秒中)内丢失了大量的服务实例心跳,这时候Eureka Server会开启自我保护机制,不会剔除该服务(该现象可能出现在如果网络不通但是Eureka Client未出现宕机,此时如果换做别的注册中心如果一定时间内没有收到心跳会将剔除该服务,这样就出现了严重失误,因为客户端还能正常发送心跳,只是网络延迟问题,而保护机制是为了解决此问题而产生的)。

Eureka Server 进入自我保护机制,会出现以下几种情况:

  1. Eureka 不再从注册列表中移除因为长时间没收到心跳而应该过期的服务
  2. Eureka仍然能够接受新服务的注册和查询请求,但是不会被同步到其它节点上(即保证当前节点依然可用)
  3. 当网络稳定时,当前实例新的注册信息会被同步到其它节点中

Eureka 自我保护机制是为了防止误杀服务而提供的一个机制。当个别客户端出现心跳失联时,则认为是客户端的问题,剔除掉客户端;当 Eureka 捕获到大量的心跳失败时,则认为可能是网络问题,进入自我保护机制;当客户端心跳恢复时,Eureka 会自动退出自我保护机制。

如果在保护期内刚好这个服务提供者非正常下线了,此时服务消费者就会拿到一个无效的服务实例,即会调用失败。对于这个问题需要服务消费者端要有一些容错机制,如重试,断路器等。

如何禁止自我保护机制?

配置项

#关闭Eureka自我保护机制,默认是true
eureka.server.enable-self-preservation=false
# 默认90秒没有收到Eureka Client的心跳包就剔除服务,修改为2秒 ,单位毫秒
eureka.server.eviction-interval-timer-in-ms=2000
           
#心跳检测与续约时间
#开发时没置小些,保证服务关闭后注册中心能即使剔除服务
#Eureka Client 向 Eureka Server发送心跳的时间间隔,单位为秒(默认是30秒)
eureka.instance.lease-renewal-interval-in-seconds=1
#Eureka Server在收到最后一次心跳后等待时间上限,单位为秒(默认是90秒),超时将剔除服务
eureka.instance.lease-expiration-duration-in-seconds=2
           

出现下图所示,则代表自我保护机制关闭

SpringCloud-Eureka(注册中心)
自我保护机制关闭后,当Erueka Client掉线后,Server端会立马将该服务剔除,不会再进行保留

继续阅读