SpringCloud之Eureka Server注册和发现

demo代码放在github上 ,需要的请点这里 传送门

一. 服务注册和发现

 

image-20210513144838732

服务提供者、服务消费者、服务注册中心三者的关系

  • 各个微服务在启动时,将自己的网络地址等信息注册到服务注册中心,服务注册中心会存储这些信息

  • 服务消费者可从服务注册中心查询服务提供者的网络地址,并使用该地址调用服务提供者的接口

  • 各个微服务与服务注册中心使用一定机制(如心跳)通信。服务注册中心若长时间无法与某微服务实例通信,就会注销该实例

  • 微服务网络地址发生变更(例如实例增减或者IP端口发生变化等)时,会重新注册到服务发现组件。使用这种方式,服务消费者就无需人工修改提供者的网络地址

1. Eureka Server 注册中心搭建步骤

  1. 创建SpringBoot工程,添加eureka-server的起步依赖

    <--SpringBoot 版本使用的是 2.4.5 -->
         <dependency>
                <groupId>org.springframework.cloud</groupId>
                <artifactId>spring-cloud-starter-netflix-eureka-server</artifactId>
            </dependency>
         <dependencyManagement>
            <dependencies>
                <dependency>
                    <groupId>org.springframework.cloud</groupId>
                    <artifactId>spring-cloud-dependencies</artifactId>
                    <version>2020.0.2</version>
                    <type>pom</type>
                    <scope>import</scope>
                </dependency>
            </dependencies>
        </dependencyManagement>

     

  2. 配置文件中添加eureka server相关配置

    spring.application.name=eurekaServer
    server.port=8761
    #收否从Eureka server获取注册信息,默认为true,因为当前应用是一个单点的Eureka server
    eureka.client.fetch-registry=false
    #是否将自己注册到Eureka Server
    eureka.client.register-with-eureka=false 
    #设置于Eureka server交互的地址,查询和注册服务都需要该地址
    eureka.client.service-url.defaultZone=http://localhost:8761/eureka
  3. 启动类添加注解@EnableEurekaServer

    image-20210513154543896

2. Eureka Client客户端搭建步骤

Eureka Client客户端主要包括服务提供者和消费者,需要把这两个都注册到注册中心上.

1. 服务提供者

主要是使用Mybatis-plus从数据库获取用户信息,使用Mybatis-plus方便对单表进行操作

  1. 添加Eureka client依赖

     <dependency>
           <groupId>org.springframework.cloud</groupId>
           <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
       </dependency>
       
       <dependencyManagement>
            <dependencies>
                <dependency>
                    <groupId>org.springframework.cloud</groupId>
                    <artifactId>spring-cloud-dependencies</artifactId>
                    <version>2020.0.2</version>
                    <type>pom</type>
                    <scope>import</scope>
                </dependency>
            </dependencies>
        </dependencyManagement>
  2. 配置文件中添加Eureka Client相关配置

    server.port=8000
    eureka.client.service-url.defaultZone=http://localhost:8761/eureka
    eureka.instance.prefer-ip-address=true

image-20210513233224535

2. 服务消费者

  1. 添加Eureka client依赖

    <dependency>
           <groupId>org.springframework.cloud</groupId>
           <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
       </dependency>
       
       <dependencyManagement>
            <dependencies>
                <dependency>
                    <groupId>org.springframework.cloud</groupId>
                    <artifactId>spring-cloud-dependencies</artifactId>
                    <version>2020.0.2</version>
                    <type>pom</type>
                    <scope>import</scope>
                </dependency>
            </dependencies>
        </dependencyManagement>

     

  2. 添加配置文件

    server.port=8081
    eureka.client.service-url.defaultZone=http://localhost:8761/eureka
    eureka.instance.prefer-ip-address=true
  3. 编写cotroller调用服务提供者的API接口

    在MoiveserviceApplication启动类中添加注册RestTemplate的Bean

     @Bean
        public RestTemplate restTemplate()
        {
            return new RestTemplate();
        }

    在controller类中调用API接口

    @Autowired
    private RestTemplate restTemplate;
    ​
    @GetMapping("/user/{id}")
    public User findById(@PathVariable long id)
    {
        //地址使用hardCode方式不可取
        return restTemplate.getForObject("http://localhost:8000/"+id,User.class);
    }

二. 高可用服务注册中心

1. Eureka高可用的作用

在微服务架构这样的分布式环境中,我们需要充分考虑发生故障的情况,很难保证单节点的Eureka服务能提供100%不间断的服务,如果Eureka无响应了,整个项目就会出现问题,所以在生成环境中必须对各个组件进行高可用部署,要保障Eureka随时都能提供服务的情况下,最好的方式就是采用Eureka的集群模式,也就是搭建Eureka的高可用。

2. Eureka高可用的搭建(双机)

还是使用上面的单节点Eureka server进行改造

  1. 对配置文件的修改:新增2个配置文件:application-peer1.properties 和 application-peer2.properties,加上application.propertites文件,总共就3个配置文件

    image-20210514150421876

    具体配置如下

    application.propertites文件如下:

    spring.application.name=eurekaServer
    spring.profiles.active=peer1

    application-peer1.properties文件如下:

    server.port=8761
    
    #收否从Eureka server获取注册信息,默认为true,因为当前应用是一个单点的Eureka server
    #eureka.client.fetch-registry=false
    #是否将自己注册到Eureka Server
    #eureka.client.register-with-eureka=false
    
    eureka.instance.hostname=peer1
    eureka.instance.prefer-ip-address=false
    
    eureka.client.fetch-registry=true
    eureka.client.register-with-eureka=true
    #设置于Eureka server交互的地址,查询和注册服务都需要该地址
    eureka.client.service-url.defaultZone=http://peer2:8762/eureka

    application-peer2.properties文件如下:

    server.port=8762
    
    
    #收否从Eureka server获取注册信息,默认为true,因为当前应用是一个单点的Eureka server
    #eureka.client.fetch-registry=false
    #是否将自己注册到Eureka Server
    #eureka.client.register-with-eureka=false
    
    eureka.instance.hostname=peer2
    eureka.instance.prefer-ip-address=false
    
    eureka.client.register-with-eureka=true
    eureka.client.fetch-registry=true
    #设置于Eureka server交互的地址,查询和注册服务都需要该地址
    eureka.client.serviceUrl.defaultZone=http://peer1:8761/eureka
  2. 由于在同一台电脑上搭建双节点Eureka集群,需要使用不同的hostName,所以需要去修改hosts文件,让上面配置的hostname能在本地正确的访问到

    image-20210514151112680

  3. 通过spring.profiles.active属性分别来启动peer1 和peer2

        • 启动peer1

          image-20210514151419951

        • 启动peer2

          image-20210514151332340

          也可先打包后在通过命令 java -jar eurekaserver-1.0.0.jar --spring.profiles.active=peer1 和 java -jar eurekaserver-1.0.0.jar --spring.profiles.active=peer1来分别启动2个应用。

      1. 分别访问http://peer1:8761http://peer2:8762

        • peer1:8761

        image-20210514151907404

        • peer2:8762

        image-20210514151954312

3. 搭建过程中遇到的问题

问题一: 启动过程中报错,com.netflix.discovery.shared.transport.TransportException: Cannot execute request on any known server

image-20210514153559608

由于我们搭建的是双机的Eureka集群,刚刚才启动一台,找不到另外peer2的服务,当时一看启动就报错了,还以为哪里出什么问题了呢,等两个服务都启动起来就好了。

问题二:注册中心出现在unavaliable-replicas上面

image-20210514153233619

  • 当只启动了一个服务,去访问http://peer1:8761时会出现上面的情况

  • 如果把eureka.instance.prefer-ip-address=true的话也会出现上面的情况,请检查application配置文件,配置如下,

    eureka.instance.prefer-ip-address=false
    eureka.client.register-with-eureka=true
    eureka.client.fetch-registry=true

三. 用户认证

前面的单节点还是集群的Eureka server注册中心,都允许直接通过输入地址和端口号就可以匿名访问,但是在实际项目中必须经过用户认证后才允许访问Eureka server。

1. 搭建步骤

  1. 添加security的依赖

    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-security</artifactId>
    </dependency>
  2. 修改配置文件,在配置文件中添加用户名和密码,设置defaultZone=http://name:password@ip:prot/eureka

    #application.propertites
    spring.security.user.name=root
    spring.security.user.password=123456
    #application-peer1.propertites
    eureka.client.service-url.defaultZone=http://root:123456@peer2:8762/eureka
    #application-peer1.propertites
    eureka.client.service-url.defaultZone=http://root:123456@peer1:8761/eureka

image-20210514162726094

image-20210514162756777

  1. 关闭Spring Security的CSRF认证,新建一个WebSecurityConfig的配置类,并继承WebSecurityConfigurerAdapter类,重写里面的configure方法

    @Configuration
    @EnableWebSecurity
    public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
    
        @Override
        protected void configure(HttpSecurity http) throws Exception {
            http.csrf().disable();//关闭csrf
            super.configure(http);
        }

     

    image-20210514163117035

  2. 访问页面并输入用户名和密码

    image-20210514163616724

  3. image-20210514163655110

     

2. 搭建过程中遇见的问题

问题一:启动过程中报错,com.netflix.discovery.shared.transport.TransportException: Cannot execute request on any known server

image-20210514153559608

如果没有上面搭建过程的第3步的话,没有关闭spring security的csrf认证的话,就会抛出上面的错误。

 

1.1 actuator微服务信息服务

  • 主机名称: 服务名称修改

    在实际工作中在eureka服务注册中心只需要暴露服务名称,不需要将主机名称暴露,在application.yml配置文件中添加instance-id如下配置

    eureka:
    client:
      fetch-registry: true
      register-with-eureka: true
      service-url:
        defaultZone: http://localhost:7001/eureka,http://localhost2:7002/eureka
    instance:
      instance-id: payment8001

    image-20211129102735994

  • 访问信息有Ip信息提示

    在实际工作中微服务可能部署到多台服务器中,在服务注册中心可以查看服务具体部署到那台机器上的,添加配置prefer-ip-address

    eureka:
    client:
      fetch-registry: true
      register-with-eureka: true
      service-url:
        defaultZone: http://localhost:7001/eureka,http://localhost2:7002/eureka
    instance:
      instance-id: payment8002
      prefer-ip-address: true

    image-20211129103126728

1.2 微服务提供者集群

消费者访问微服务提供者集群时需要使用负载均衡注解@LoadBalanced, 而且不能使用固定的IP地址,需要使用注册中心的服务名称

image-20211129100834420

image-20211129100934511

Ribbon和Eureka整合后Consumer可以直接调用服务而不再关心地址和端口号,且该服务还有负载功能

1.3 服务发现discovery

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

1.4 Eureka自我保护

概述

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

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

什么是自我保护模式

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

如果在Eureka server的首页看到如下这段提示,则说明eureka进入了保护模式

image-20211129111349241

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

它的设计哲学就是宁可保留错误的服务注册信息,也不盲目注销任何可能健康的服务实例。一句话:好死不如赖活着,使用自我保护模式,可以让eureka集群更加的健壮、稳定。

如何关闭自我保护模式

在配置文件中添加配置enable-self-preservation就可以关闭自我保护模式,默认时开启,默认值为true

eureka:
instance:
  hostname: localhost1 #eureka服务端的实例明
client:
#   false表示不向注册中心注册自己
  register-with-eureka: false
#   false表示自己端就是注册中心,职责就是维护服务实例,并不需要去检索服务
  fetch-registry: false
#   设置与eureka server交互的地址查询服务和注册服务都需要依赖这个地址
  service-url:
#     defaultZone: http://${eureka.instance.hostname}:${server.port}/eureka/
    defaultZone: http://localhost2:7002/eureka/
server:
  enable-self-preservation: false

image-20211129114204181

客户端的话可以设置心跳时间和等待心跳时间上限

eureka:
client:
  fetch-registry: true
  register-with-eureka: true
  service-url:
    defaultZone: http://localhost:7001/eureka,http://localhost2:7002/eureka
instance:
  instance-id: payment8001
  prefer-ip-address: true
  #Eureka客户端向服务端发生心跳的时间间隔,默认是30s
  lease-renewal-interval-in-seconds: 1
  #Eureka服务端在收到最后一次心跳后等待时间上限,默认是90秒,超时将剔除服务
  lease-expiration-duration-in-seconds: 2

2. Zookeeper服务注册与发现

posted @ 2021-05-14 10:11  肖恩雷  阅读(242)  评论(0编辑  收藏  举报