Eureka 介绍

1. 背景:在传统应用中,组件之间的调用,通过有规范的约束的接口来实现,从而实现不同模块间良好的协作。但是被拆分成微服务后,每个微服务实例的网络地址都可能动态变化,数量也会变化,使得原来硬编码的地址失去了作用。需要一个中心化的组件来进行服务的登记和管理。
2. 概念:实现服务治理,即管理所有的服务信息和状态。

  注册中心相当于买票乘车,只看有没有票(有没有服务),有就去买票(获取注册列表),然后乘车(调用)。不必关心有多少火车在运行。

3. 注册中心好处:不用关心有多少提供方。

4.注册中心有哪些:Eureka,Nacos,Consul,Zookeeper等。

5. 服务注册与发现包括两部分,一个是服务器端,另一个是客户端。

  Server是一个公共服务,为Client提供服务注册和发现的功能,维护注册到自身的Client的相关信息,同时提供接口给Client获取注册表中其他服务的信息,使得动态变化的Client能够进行服务间的相互调用。

  Client将自己的服务信息通过一定的方式登记到Server上,并在正常范围内维护自己信息一致性,方便其他服务发现自己,同时可以通过Server获取到自己依赖的其他服务信息,完成服务调用,还内置了负载均衡器,用来进行基本的负载均衡。

6. Eureka:是一个RESTful风格的服务,是一个用于服务发现和注册的基础组件,是搭建Spring Cloud微服务的前提之一,它屏蔽了Server和client的交互细节,使得开发者将精力放到业务上。

7. serverA从serverB同步信息,则serverB是serverA的peer。

client功能

  1. 注册:每个微服务启动时,将自己的网络地址等信息注册到注册中心,注册中心会存储(内存中)这些信息。
  2. 获取服务注册表:服务消费者从注册中心,查询服务提供者的网络地址,并使用该地址调用服务提供者,为了避免每次都查注册表信息,所以client会定时去server拉取注册表信息到缓存到client本地。
  3. 心跳:各个微服务与注册中心通过某种机制(心跳)通信,若注册中心长时间和服务间没有通信,就会注销该实例。
  4. 调用:实际的服务调用,通过注册表,解析服务名和具体地址的对应关系,找到具体服务的地址,进行实际调用。

server注册中心功能

  1. 服务注册表:记录各个微服务信息,例如服务名称,ip,端口等。

    注册表提供 查询API(查询可用的微服务实例)和管理API(用于服务的注册和注销)。

  2. 服务注册与发现:注册:将微服务信息注册到注册中心。发现:查询可用微服务列表及其网络地址。

  3. 服务检查:定时检测已注册的服务,如发现某实例长时间无法访问,就从注册表中移除。

Eureka Server与Eureka Client之间的联系主要通过心跳的方式实现。心跳(Heartbeat)即Eureka Client定时向Eureka Server汇报本服务实例当前的状态,维护本服务实例在注册表中租约的有效性。

Eureka Client将定时从Eureka Server中拉取注册表中的信息,并将这些信息缓存到本地,用于服务发现。

Eureka高可用

  高可用:可以通过运行多个Eureka server实例并相互注册的方式实现。Server节点之间会彼此增量地同步信息,从而确保节点中数据一致。

因此Eureka实现了AP,没有实现C的原因。

节点配置:

是否将自己注册到其他Eureka Server,默认为true 需要
  eureka.client.register-with-eureka=true
  #是否从eureka server获取注册信息, 需要
  eureka.client.fetch-registry=true
  #设置服务注册中心的URL,用于client和server端交流
  #此节点应向其他节点发起请求
  eureka.client.serviceUrl.defaultZone=http://ek2.com:7902/eureka/
  #主机名,必填(hostname用来查找主机地址的,appname表示分组)
  eureka.instance.hostname=ek1.com
  management.endpoint.shutdown.enabled=true
  #web端口,服务是由这个端口处理rest请求的(tomcat端口号)
  server.port=7901

**Renew 续租,心跳**

  Eureka客户需要每30秒发送一次心跳来续租

  客户端需要通知Eureka服务器实例仍然是活动的。如果服务器在90秒内没有看到更新,它将从其注册表中删除实例。

**Fetch Registry(注册信息抓取)

  Eureka客户端从服务器获取注册表信息并将其缓存在本地。之后,客户端使用这些信息来查找其他服务。

  通过获取上一个获取周期和当前获取周期之间的增量更新,可以定期(每30秒)更新此信息。

  节点信息在服务器中保存的时间更长(大约3分钟),因此获取节点信息时可能会再次返回相同的实例。Eureka客户端自动处理重复的信息。

  在获得增量之后,Eureka客户机通过比较服务器返回的实例计数来与服务器协调信息,如果由于某种原因信息不匹配,则再次获取整个注册表信息。

## Cancel

  Eureka客户端在关闭时向Eureka服务器发送取消请求。这将从服务器的实例注册表中删除实例,从而有效地将实例从通信量中取出。

## Time Lag(同步时间延迟)

  来自Eureka客户端的所有操作可能需要一段时间才能反映到Eureka服务器上,然后反映到其他Eureka客户端上。这是因为eureka服务器上的有效负载缓存,它会定期刷新以反映新信息。Eureka客户端还定期地获取增量。因此,更改传播到所有Eureka客户机可能需要2分钟。

## Communication mechanism

通讯机制

  Http协议下的Rest请求,默认情况下Eureka使用Jersey和Jackson以及JSON完成节点间的通讯.

 

客户端配置选项

#续约发送间隔默认30秒,心跳间隔
eureka.instance.lease-renewal-interval-in-seconds=5
#表示eureka client间隔多久去拉取服务注册信息,默认为30秒,对于api-gateway,如果要迅速获取服务注册状态,可以缩小该值,比如5秒
eureka.client.registry-fetch-interval-seconds=5
# 续约到期时间(默认90秒)
eureka.instance.lease-expiration-duration-in-seconds=60

服务器端配置选项

#关闭自我保护模式
eureka.server.enable-self-preservation=false
#失效服务间隔
eureka.server.eviction-interval-timer-in-ms=3000

EurekaClient

  EurekaClient 可以在客户端获取eureka服务器上的注册者信息

**org.springframework.cloud.client.discovery与com.netflix.discovery.DiscoveryClient**


org.springframework.cloud.client.discovery是SpringCloud对注册中心client的抽象封装,提供公用功能

org.springframework.cloud.client.discovery定义用来服务发现的客户端接口,是客户端进行服务发现的核心接口,是spring cloud用来进行服务发现的顶级接口,在common中可以看到其地位。在Netflix Eureka和Consul中都有具体的实现类。

代表通用于服务发现的读操作,例如在 eureka或consul中。

String description();//获取实现类的描述。
List<String> getServices();//获取所有服务实例id。
List<ServiceInstance> getInstances(String serviceId);//通过服务id查询服务实例信息列表。

com.netflix.discovery.DiscoveryClient为Eureka注册中心客户端的接口,功能更丰富

## 自我保护机制:

  Eureka在CAP理论当中是属于AP , 也就说当产生网络分区时,Eureka保证系统的可用性,但不保证系统里面数据的一致性

  默认开启,服务器端容错的一种方式,即短时间心跳不到达仍不剔除服务列表里的节点

  eureka界面提示:
    EMERGENCY! EUREKA MAY BE INCORRECTLY CLAIMING INSTANCES ARE UP WHEN THEY'RE NOT. RENEWALS ARE LESSER THAN THRESHOLD AND HENCE THE INSTANCES ARE NOT BEING EXPIRED JUST TO BE SAFE.

  默认情况下,Eureka Server在一定时间内,没有接收到某个微服务心跳,会将某个微服务注销(90S)。但是当网络故障时,微服务与Server之间无法正常通信,上述行为就非常危险,因为微服务正常,不应该注销。

  Eureka Server通过自我保护模式来解决整个问题,当Server在短时间内丢失过多客户端时,那么Server会进入自我保护模式,会保护注册表中的微服务不被注销掉。当网络故障恢复后,退出自我保护模式。

  思想:宁可保留健康的和不健康的,也不盲目注销任何健康的服务。**

  自我保护触发:客户端每分钟续约数量小于客户端总数的85%时会触发保护机制**

 

  使用Spring Boot2.x Actuator监控应用

pom.xml
    <dependency>
           <groupId>org.springframework.boot</groupId>
           <artifactId>spring-boot-starter-actuator</artifactId>
     </dependency>

  Spring Boot 2.0 的Actuator只暴露了health和info端点,提供的监控信息无法满足我们的需求,在1.x中有n多可供我们监控的节点,官方的回答是为了安全….

开启Eureka安全连接(eurekaServer):

spring.security.user.name=yiming
  spring.security.user.password=123

客户端连接的时候通过配置:

eureka.client.serviceUrl.defaultZone=http://用户名:密码@路径/eureka/

如果服务注册报错:  Root name 'timestamp' does not match expected ('instance') for type [simple

  是默认开启了防止跨域攻击

手动关闭(认证是在服务器端):

  在服务端增加配置类

@Configuration
@EnableWebSecurity
public class WebSecurityConfig extends WebSecurityConfigurerAdapter{

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        // TODO Auto-generated method stub
        http.csrf().disable();
        super.configure(http);
    }

}