SpringCloud Eureka注册中心的使用

Eureka是Netflix开发的服务发现框架,本身是一个基于REST的服务,主要用于定位运行在AWS域中的中间层服务,以达到负载均衡和中间层服务故障转移的目的。SpringCloud将它集成在其子项目spring-cloud-netflix中,以实现SpringCloud的服务发现功能。

服务治理

Spring Cloud封装了Netflix公司开发的Eureka来实现服务治理

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

服务注册与发现

Eureka采用了CS(Client Server)的设计架构,Eureka Server作为服务注册功能的服务器,它是服务注册中心。而系统中的其他微服务,使用Eureka的客户端连接到Eureka Server并维持心跳连接。这样系统的维护人员就可以通过Eureka Server来监控系统中各个微服务是否正常运行

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

  • 服务注册:将服务信息注册进注册中心。
  • 服务发现:从注册中心上获取服务信息。
  • 服务注册与发现的过程:启动服务注册中心,服务提供者将自己的服务注册到服务中心(以别名的形式),服务消费者以服务别名去注册中心获取服务的信息(调用地址),然后进行远程调用。服务消费者获取到服务信息后会存入本地缓存(jvm)中,默认每30s去更新一次服务信息。

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

  1. Eureka Server提供服务注册服务

    各个微服务结点通过配置启动后,会在EurekaServer中进行注册,这样EurekaServer中的服务注册表中将会存储所有可用服务节点的信息,服务节点的信息可以在界面中直观看到。

  2. Eureka Client通过注册中心进行访问

    Eureka Client是一个java客户端,用于简化Eureka Server的交互,客户端同时也具备一个内置的、使用轮询负载算法的负载均衡器。在应用启动后,将会向Eureka Server发送心跳(默认周期为30秒)。如果Eureka Server在多个心跳周期内没有接收到某个结点的心跳,EurekaServer将会从服务注册表中把这个服务节点移除(默认90秒)

Eureka Server(服务端)构建步骤

  1. 添加Eureka Server的maven依赖

    扫描二维码关注公众号,回复: 12753769 查看本文章
    <!--Eureka 服务端,老版本spring-cloud-starter-eureka-->
    <dependency>
        <groupId>org.springframework.cloud</groupId>
        <artifactId>spring-cloud-starter-netflix-eureka-server</artifactId>
    </dependency>
    
  2. 配置文件添加EurekaServer配置

    server:
      port: 7001
    eureka:
      instance:
        hostname: localhost #服务实例名称
      client:
        #false表示不向注册中心注册自己,因为自己就是注册中心
        register-with-eureka: false
        #false表示自己就是注册中心,不需要去检索服务信息
        fetch-registry: false
        service-url:
          #注册地址
          defaultZone: http://${
          
          eureka.instance.hostname}:${
          
          server.port}/eureka/
    
  3. springboot启动类上添加注解@EnableEurekaServer

    @SpringBootApplication
    @EnableEurekaServer
    public class EurekaServerApplication {
          
          
    
        public static void main(String[] args) {
          
          
            SpringApplication.run(EurekaServerApplication.class,args);
        }
    }
    

Eureka Client(客户端)构建步骤

  1. 添加Eureka Client的maven依赖

    <!--Eureka 客戶端,老版本spring-cloud-starter-eureka-->
    <dependency>
        <groupId>org.springframework.cloud</groupId>
        <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
    </dependency>
    
  2. 配置文件添加EurekaClient配置

    #服务端口号
    server:
      port: 8001
    
    #服务名称,注册到eureka上的别名
    spring:
      application:
        name: cloud-payment-service 
    
    #eureka client
    eureka:
      client:
        #是否将自己注册进eurekaServer,默认true
        register-with-eureka: true
        #是否从EurekaServer抓取已有的注册信息,默认为true,集群必须为true
        fetchRegistry: true
        service-url:
          #服务注册地址
          defaultZone: http://localhost:7001/eureka
    
  3. springboot启动类上添加注解@EnableEurekaServer

    @SpringBootApplication
    @EnableEurekaClient
    public class PaymentApplication {
          
          
    
        public static void main(String[] args) {
          
          
            SpringApplication.run(PaymentApplication.class,args);
        }
    }
    

Eureka Server集群

Eureka集群:每个Eureka服务有其他Eureka的注册信息。互相注册

Eureka Server集群:三台EurekaServer集群

  1. 修改配置文件

    ##############第一个7001##################
    server:
      port: 7001
    eureka:
      instance:
        hostname: eureka1.com  
      client:
        #false表示不向注册中心注册自己,因为自己就是注册中心
        register-with-eureka: false
        #false表示自己就是注册中心,不需要去检索服务信息
        fetch-registry: false
        service-url:
          #注册地址 。多个集群用逗号隔开。这里做的域名映射,不做也可
          defaultZone: http://eureka2.com:7002/eureka/,http://eureka3.com:7003/eureka/
          
    ##############第二个7002##################      
    server:
      port: 7002
    eureka:
      instance:
        hostname: eureka2.com
      client:
        #false表示不向注册中心注册自己,因为自己就是注册中心
        register-with-eureka: true
        #false表示自己就是注册中心,不需要去检索服务信息
        fetch-registry: false
        service-url:
          #eureka集群互相注册,这里是其他注册中心的地址
          defaultZone: http://eureka1.com:7001/eureka/,http://eureka3.com:7003/eureka/
    
    ##############第二个7003##################        
    server:
      port: 7003
    eureka:
      instance:
        hostname: eureka3.com
      client:
        register-with-eureka: false   #false表示不向注册中心注册自己
        fetch-registry: false   #false表示自己端就是注册中心
        service-url:
          defaultZone: http://eureka7002.com:7002/eureka/,http://eureka7001.com:7001/eureka/
    
  2. 三台Eureka启动,看管理页面可以看到都注册上去了

在这里插入图片描述

Eureka Client注册进Eureka集群

  1. 修配置文件defaultZone,把所有的Eureka地址填上,逗号隔开。启动项目查看服务注册成功,每个都有

    #eureka client
    eureka:
      client:
        #是否将自己注册进eurekaServer,默认true
        register-with-eureka: true
        #是否从EurekaServer抓取已有的注册信息,默认为true,集群必须为true
        fetchRegistry: true
        service-url:
          #服务注册地址 ,注册进eureka1,eureka2(eureka3省略不写太长了)
          defaultZone: http://eureka1.com:7001/eureka/,http://eureka1.com:7002/eureka/
    

Eureka Client集群

  1. 同样的服务名称(不同调用地址)启动服务提供者,注册到Eureka注册中心

    ###################服务提供者1号,8001端口###############################
    server:
      port: 8001 #端口号
    spring:
      application:
        name: cloud-payment-service #服务名称
    #eureka client
    eureka:
      client:
        register-with-eureka: true
        fetchRegistry: true
        service-url:
          #服务注册地址
          defaultZone: http://eureka1.com:7001/eureka/
          
    ###################服务提供者2号,8002端口###############################
    server:
      port: 8002 #端口号
    spring:
      application:
        name: cloud-payment-service #服务名称
    #eureka client
    eureka:
      client:
        register-with-eureka: true
        fetchRegistry: true
        service-url:
          #服务注册地址
          defaultZone: http://eureka1.com:7001/eureka/      
    
  2. 用RestTemplate调用服务,加@LoadBalanced注解,开启负载均衡,将请求地址服务逻辑名转为具体调用地址

    @Configuration
    public class ApplicationContextConfig {
          
          
    
        @Bean
        @LoadBalanced
        public RestTemplate restTemplate(){
          
          
            return new RestTemplate();
        }
    }
    
     * 服务调用地址写成服务名称
     */
    private static final String PAYMENT_URL = "http://CLOUD-PAYMENT-SERVICE/payment";
    
    @Resource
    private RestTemplate restTemplate;
    
    @GetMapping(value = "/create")
    public BaseResult create(Payment payment){
          
          
        return restTemplate.postForObject(PAYMENT_URL + "/create",payment,BaseResult.class);
    }
    

服务发现Discovery

作用:获取注册中心的服务信息。

Discovery使用

  1. springboot启动类添加注解@EnableDiscoveryClient

    @SpringBootApplication
    @EnableEurekaClient
    @EnableDiscoveryClient //Discovery
    public class PaymentApplication {
          
          
    
        public static void main(String[] args) {
          
          
            SpringApplication.run(PaymentApplication.class,args);
        }
    }
    
  2. 代码里注入DiscoveryClient,输出服务信息

    @GetMapping(value = "discovery")
    public Object discovery(){
          
          
        //获取服务列表
        List<String> list = discoveryClient.getServices();
        list.forEach(System.out::println);
        //根据服务实例名称获取实例
        List<ServiceInstance> instances = discoveryClient.getInstances("CLOUD-PAYMENT-SERVICE");
        instances.forEach(e -> {
          
          
            System.out.println("serviceId="+e.getServiceId()+"\t"+"host="+e.getHost()+
                    "\t"+"port="+e.getPort()+"\t"+"uri="+e.getUri());
        });
        return discoveryClient;
    }
    

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可能错误地声称实例在没有启动的情况下启动了。续订小于阈值,因此实例不会为了安全而过期

Eureka自我保护理论知识

某时刻有某一服务不可用了,不会立马将服务清除,依旧会对服务信息进行保存。为了防止服务实际正常运行,但是与EurekaServer之间网络不通的,EurekaServer不会立即将服务剔除。

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

在自我保护模式中,EurekaServer会保护服务注册表中的信息,不再注销任何实例。

**宁可保留错误的服务注册信息,也不盲目注销任何可能健康的服务实例。**CAP原则里的AP。

禁止Eureka自我保护

  1. EurekaServer添加配置A、B

    server:
      port: 7001
    eureka:
      instance:
        hostname: eureka1.com
      client:
        register-with-eureka: false
        fetch-registry: false
        service-url:
          defaultZone: http://eureka1.com:7001/eureka/
      server:
        #(A)关闭自己我保护机制,保证不可用服务被及时剔除,默认true
        enable-self-preservation: false
        #(B)时间改小。单位:毫秒
        eviction-interval-timer-in-ms: 2000
    
  2. EurekaClient端添加配置A、B

    #eureka client
    eureka:
      client:
        register-with-eureka: true
        fetchRegistry: true
        service-url:
          defaultZone: http://eureka1.com:7001/eureka/
      instance:
        instance-id: payment8001 
        prefer-ip-address: true
        #(A)Eureka客户端向服务端发送心跳的时间间隔 单位秒,默认30秒
        lease-renewal-interval-in-seconds: 1
        #(B)Eureka服务端在收到最后一次心跳后等待时间上线,单位秒(默认90s),超出时将剔除服务
        lease-expiration-duration-in-seconds: 2
    
  3. 测试服务是否及时剔除

Eureka 2.0 (Discontinued)

The existing open source work on eureka 2.0 is discontinued. The code base and artifacts that were released as part of the existing repository of work on the 2.x branch is considered use at your own risk.

Eureka 1.x is a core part of Netflix’s service discovery system and is still an active project.

eureka2.0上现有的开源工作已经停止。作为2.x分支上现有工作存储库的一部分发布的代码库和工件被视为使用风险自负。

eureka1.x是Netflix服务发现系统的核心部分,目前仍是一个活跃的项目。

猜你喜欢

转载自blog.csdn.net/zhaoqingquanajax/article/details/114499108