菜单 学习猿地 - LMONKEY

VIP

开通学习猿地VIP

尊享10项VIP特权 持续新增

知识通关挑战

打卡带练!告别无效练习

接私单赚外块

VIP优先接,累计金额超百万

学习猿地私房课免费学

大厂实战课仅对VIP开放

你的一对一导师

每月可免费咨询大牛30次

领取更多软件工程师实用特权

入驻
120
0

Eureka

原创
05/13 14:22
阅读数 12083

Eureka

@Author:wangyq

@Date:2021年4月23日

一、简介

​ Eureka是一种基于REST (Representational State Transfer, Representational State Transfer)的服务,主要用于AWS云中的服务定位,用于中间层服务器的负载平衡和故障转移。SpringCloud将它集成在其子项目spring-cloud-netflix中,以实现SpringCloud的服务发现功能。Eureka2.0于2018年7月已停止更新!Eureka1.x正常使用

image

二、初识Eureka

1. 运行原理

image

  1. 微服务通过固定时间发送心跳到Eureka服务器实现注册
  2. 消费者通过Eureka服务器获取到服务的地址
  3. 消费者根据地址远程访问服务

注册中心中可以实现集群负载均衡

2. 依赖

​ a. 服务器:

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

​ b. 客户端(微服务):

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

3. 配置文件

​ a. 服务器:

server:
  port: 7001

eureka:
  instance:
    hostname: eureka7001.com
  client:
    # false表示不向注册中心注册自己
    register-with-eureka: false
    # false表示自己就是注册中心
    fetch-registry: false
    # 注册集群其他的服务器
    service-url:
      defaultZone:
        http://eureka7002.com:7002/eureka/,
        http://eureka7003.com:7003/eureka/

#  server:
#    # 关闭自我保护,将AP模式改为CP模式,保证不可用服务迅速被清除
#    enable-self-preservation: false
#    # 修改清除时间
#    eviction-interval-timer-in-ms: 2000

​ b. 客户端(微服务):

server:
  port: 8001

spring:
  application:
    name: cloud-payment-service        #注册中心的名字  这里很关键,消费者调用是通过name调用的
  datasource:
    type: com.alibaba.druid.pool.DruidDataSource            # 当前数据源操作类型
    driver-class-name: com.mysql.cj.jdbc.Driver             
    url: jdbc:mysql://localhost:3306/db2019?useUnicode=true&characterEncoding=utf-8&useSSL=false
    username: root
    password: 123456

mybatis:
  mapperlocations: classpath:mapper/*.xml
  type-aliases-package: com.ergwang.springcloud.entities    # 所有Entity别名类所在包

eureka:
  instance:
    # 主机名  显示在注册中心的名字
    instance-id: payment8001
    # 显示ip  鼠标放在注册中心名字上显示ip
    prefer-ip-address: true

#    # Eureka客户端向服务器发送心跳的时间间隔,单位秒(默认30秒)
#    lease-renewal-interval-in-seconds: 1
#    # Eureka服务器收到最后一次心跳后,等待时间的上限,单位秒(默认90秒),超时剔除服务注册信息
#    lease-expiration-duration-in-seconds: 2

  client:
    # 表示是否要将自己注册进去EurekaServer  默认true
    register-with-eureka: true
    # 是否从EurekaServer中抓去已注册的信息,默认true。单点无所谓,集群必须true才能配合ribbon使用负载均衡
    fetch-registry: true
    service-url:
      # 单机
      # defaultZone: http://localhost:7001/eureka/
      #集群
      defaultZone:
        http://localhost:7001/eureka/,
        http://localhost:7002/eureka/,
        http://localhost:7003/eureka/

4. 启动类注解

​ a. 服务器:

@EnableEurekaServer

​ b. 客户端(微服务):

@EnableEurekaClient

三、服务发现Discovery(查看注册在Eureka中的服务)

1. 简介

对于注册进Eureka里面的微服务,可以通过服务发现Discovery来获得该服务的信息

2. jar包

import org.springframework.cloud.client.discovery.DiscoveryClient;

3. 实现

​ a. 客户端(微服务)的Controller中:

@Resource
private DiscoveryClient discoveryClient;

@GetMapping("/discover")
    public Object discover(){
        List<String> services = discoveryClient.getServices();
        // 遍历打印所有的服务的名称
        for (String element : services){
            log.info("********* element:"+ element +"*********");
        }

        List<ServiceInstance> instances = 
            				discoveryClient.getInstances("Eureka中显示的服务名称,如:cloud-payment-service");
        // 遍历打印一个服务的集群服务器所有的服务 
        for (ServiceInstance element : instances) {
            log.info(element.getInstanceId()+"\t"+
                    element.getHost()+"\t"+
                    element.getPort()+"\t"+
                    element.getUri());
        }
        return this.discoveryClient;
    }

​ b. 客户端(微服务)启动类添加注解:

@EnableEurekaClient

四、Eureka的自我保护机制

1. 简介

Eureka是CAP理论中的AP模式,即只能保证可用性( Availability)和分区容错性(Partition tolerance),放弃一致性(Consistency)。

​ 默认情况下EurekaClient定时向EurekaServer端发送心跳包,如果Eureka的server端在一定时间内(默认90秒)没有收到EurekaClient发送心跳包,便会直接从服务注册列表中剔除该服务,但是在短时间(90秒中)内丢失了大量的服务实例心跳,这时候EurekaServer会开启自我保护机制,不会剔除该服务

​ 该现象可能出现在网络不通的情况,但是EurekaClient未出现宕机,此时如果换做别的注册中心,可能一定时间内没有收到心跳会将剔除该服务,这样就出现了严重失误,因为客户端还能正常发送心跳,只是网络延迟问题,而保护机制是为了解决此问题而产生的。

2. 现象

image

正常启动Eureka服务器,所有微服务集群,运行过程中,突然关闭集群中的一个服务(模拟断网),Eureka服务器的web页面出现了专业一段提醒:

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.

3. 关闭自我保护(默认打开)

  1. 在注册中心关闭自我保护机制,修改检查失效服务的时间:

    server:
      port: 7001
    
    eureka:
      instance:
        hostname: eureka7001.com
      client:
        #false 表示不向注册中心注册自己
        register-with-eureka: false
        #false表示自己就是注册中心
        fetch-registry: false
        service-url:
          defaultZone:
            http://eureka7002.com:7002/eureka/
    
    
    # 关闭自我保护
      server:
        # 关闭自我保护,将AP模式改为CP模式,保证不可用服务迅速被清除
        enable-self-preservation: false
        # 修改清除时间,默认90秒
        eviction-interval-timer-in-ms: 2000
    
  2. 在client(微服务端)修改、缩短微服务心跳时间:

    eureka:
      instance:
        # 主机名
        instance-id: payment8001
        # 显示ip
        prefer-ip-address: true
        client:
        # 表示是否要将自己注册进去EurekaServer 默认true
        register-with-eureka: true
        # 是否从EurekaServer中抓去已注册的信息,默认true。单点无所谓,集群必须true才能配合ribbon使用负载均衡
        fetch-registry: true
        service-url:
          # 单机
          # defaultZone: http://localhost:7001/eureka/
          #集群
          defaultZone:
            http://eureka7001.com:7001/eureka/,
            http://eureka7002.com:7002/eureka/
    
    
        # Eureka客户端向服务器发送心跳的时间间隔,单位秒(默认30秒)
        lease-renewal-interval-in-seconds: 1
        # Eureka服务器收到最后一次心跳后,等待时间的上限,单位秒(默认90秒),超时剔除服务注册信息
        lease-expiration-duration-in-seconds: 2
    

参考资料

尚硅谷视频:https://www.bilibili.com/video/BV18E411x7eT

发表评论

0/200
120 点赞
0 评论
收藏
为你推荐 换一批