SpringCloud学习之三Eureka服务注册与发现

5.Eureka服务注册与发现

5.1 是什么

Netflix在设计Eureka时遵守的就是AP原则

Eureka是Netflix的一个子模块,也是核心模块之一。Eureka是一个基于REST的服务,用于定位服务,以实现云端中间层服务发现和故障转移。服务注册与发现对于微服务架构来说是非常重要的,有了服务发现与注册,只需要使用服务的标识符,就可以访问服务,而不需要修改服务调用的配置文件了。功能类似于dubbo的注册中心,比如Zookeeper

 

类似于大厦的楼层指引牌

5.2 原理讲解

Eureka的基本架构

Spring Cloud封装了Netflix公司开发的Eureka模块来实现服务注册和发现(请对比Zookeeper

 

Eureka采用了C-S的设计架构。EurekaServer作为服务注册功能的服务器,它是服务注册中心。

 

而系统中的其他微服务,使用Eureka的客户端连接到Eureka Server并维持心跳连接。这样系统的维护人员就可以通过Eureka Server来监控系统中各个微服务是否正常运。SpringCloud的一些其他模块(比如Zuul)就可以通过Eureka Server来发现系统中的其他微服务,并执行相关的逻辑。

请注意和Dubbo的架构对比


Eureka包含两个组件:Eureka ServerEureka Client

EurekaServer提供服务注册服务

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

 

Eurekaclient是一个Java客户端,用于简化EurekaServer的交互,客户端同时也具备一个内置的、使用Eureka Server在多个心跳周期内没有接收到某个节点的心中,EurekaServer将会从服务注册表中把这个服务节点移除(默认90秒)

三大角色

l  Eureka Server提供服务注册和发现

l  Service Provider服务提供方将自身服务注册到Eureka,从而使服务消费方能够找到

l  Service Consumer服务方从Eureka获取注册服务列表,从而能够消费服务

盘点下目前我们的工程情况

l  总父工程

l  通用模块api

l  服务提供者Provider

l  服务消费者Consumer

5.3 构建步骤

l  microservicecloud-eureaka-7001 eureka服务注册中心Module

1.      新建microservicecloud-eureka-7001

 

假如我需引入cloud的一个新技术组件

第一步:新增一个相关的maven坐标

                  Eureka

<!--修改后立即生效,热部署-->
        <dependency>
<groupId>org.springframework</groupId>
    <artifactId>springloaded</artifactId>
          </dependency>

         Zuul

第二步 在主启动类上面,标注的启动该组件技术的相关注解标签

 

第三步 java业务逻辑编码

          @EnableEurekaServer

Zuul

           @EnableZuulProxy

 

 

2.      POM

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
        
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
        
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0http://maven.apache.org/xsd/maven-4.0.0.xsd">
   
<parent>
       
<artifactId>microservicecloud</artifactId>
       
<groupId>com.atguigu.springcloud</groupId>
       
<version>1.0-SNAPSHOT</version>
   
</parent>
   
<modelVersion>4.0.0</modelVersion>

   
<artifactId>microservicecloud-eureka-7001</artifactId>

   
<dependencies>
       
<!--eureka-server服务端-->
       
<dependency>
           
<groupId>org.springframework.cloud</groupId>
           
<artifactId>spring-cloud-starter-eureka-server</artifactId>
       
</dependency>
       
<!--修改后立即生效,热部署-->
       
<dependency>
           
<groupId>org.springframework</groupId>
           
<artifactId>springloaded</artifactId>
       
</dependency>
       
<dependency>
           
<groupId>org.springframework.boot</groupId>
           
<artifactId>spring-boot-devtools</artifactId>
       
</dependency>
   
</dependencies>
</
project>

 

3.      YML

server:
 
port: 7001
 

eureka:
 
instance:
    hostname: localhost   #eureka服务端的实例名称
 
client:
   
register-with-eureka: false    #flase表示不向注册中心注册自己
   
fetch-registry: false  #flase表示自己端就是注册中心,我的职责就是维护服务实例,并不需要检索服务
   
service-url:
     
defautZone: http://${eureka.instance.hostname}:${server.port}/eureka/
     
#设置与Eureka Server交互的地址查询服务和注册服务都需要依赖这个地址

 

4.      EurekaServer7001_App主启动类

package com.atguigu.springcloud;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.netflix.eureka.server.EnableEurekaServer;

@SpringBootApplication
@EnableEurekaServer //EurekaServer
服务端启动类,接受其它微服务注册进来
public class EurekaServer7001_App {
   
public static void main(String[] args) {
       
SpringApplication.run(EurekaServer7001_App.class,args);
  
 }
}

 

5.      测试

http://localhost:7001

结果页面

No application available没有服务被发现

因为没有注册服务进来当然不可能有服务被发现

microservicecloud-provider-dept-8001将已有的部门微服务注册进eureka服务中心

l  修改microservicecloud-provider-dept-8001

l  POM

1.      修改部分

<!--将微服务provider注册进eureka-->
<dependency>
   
<groupId>org.springframework.cloud</groupId>
   
<artifactId>spring-cloud-starter-eureka</artifactId>
</
dependency>
<
dependency>
   
<groupId>org.springframework.cloud</groupId>
   
<artifactId>spring-cloud-starter-config</artifactId>
</
dependency>

 

2.      完整部分

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
        
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
        
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0http://maven.apache.org/xsd/maven-4.0.0.xsd">
   
<parent>
       
<artifactId>microservicecloud</artifactId>
       
<groupId>com.atguigu.springcloud</groupId>
       
<version>1.0-SNAPSHOT</version>
   
</parent>
   
<modelVersion>4.0.0</modelVersion>

   
<artifactId>microservicecloud-provider-dept-8001</artifactId>

   
<dependencies>
       
<!-- 引入自己定义的api通用包,可以使用Dept部门Entity-->
        <dependency>
           
<groupId>com.atguigu.springcloud</groupId>
           
<artifactId>microservicecloud-api</artifactId>
           
<version>${project.version}</version>
       
</dependency>
    
   <!--将微服务provider注册进eureka-->
        <dependency>
           <groupId>org.springframework.cloud</groupId>
           <artifactId>spring-cloud-starter-eureka</artifactId>
        </dependency>
        <dependency>
           <groupId>org.springframework.cloud</groupId>
           <artifactId>spring-cloud-starter-config</artifactId>
        </dependency>
       
<!-- actuator监控信息完善 -->
       
<dependency>
           
<groupId>org.springframework.boot</groupId>
           
<artifactId>spring-boot-starter-actuator</artifactId>
       
</dependency>
       
<dependency>
           
<groupId>junit</groupId>
           
<artifactId>junit</artifactId>
       
</dependency>
       
<!-- mysql驱动包 -->
       
<dependency>
           
<groupId>mysql</groupId>
           
<artifactId>mysql-connector-java</artifactId>
       
</dependency>
       
<!-- 连接池 -->
       
<dependency>
           
<groupId>com.alibaba</groupId>
           
<artifactId>druid</artifactId>
       
</dependency>
       
<!-- 日志 -->
       
<dependency>
           
<groupId>ch.qos.logback</groupId>
           
<artifactId>logback-core</artifactId>
       
</dependency>
       
<!-- mybatis的整合 -->
       
<dependency>
           
<groupId>org.mybatis.spring.boot</groupId>
           
<artifactId>mybatis-spring-boot-starter</artifactId>
       
</dependency>
       
<!-- boot的jetty 内置tomcat插件-->
        <dependency>
           
<groupId>org.springframework.boot</groupId>
           
<artifactId>spring-boot-starter-jetty</artifactId>
       
</dependency>
       
<dependency>
           
<groupId>org.springframework.boot</groupId>
           
<artifactId>spring-boot-starter-web</artifactId>
       
</dependency>
       
<dependency>
           
<groupId>org.springframework.boot</groupId>
           
<artifactId>spring-boot-starter-test</artifactId>
       
</dependency>
       
<!-- 修改后立即生效,热部署 -->
       
<dependency>
           
<groupId>org.springframework</groupId>
 
          <artifactId>springloaded</artifactId>
       
</dependency>
       
<dependency>
           
<groupId>org.springframework.boot</groupId>
           
<artifactId>spring-boot-devtools</artifactId>
       
</dependency>
   
</dependencies>

</
project>

 

l  YML

1.      修改部分

eureka:
 
client:   #客户端注册进eureka服务列表中
    service-url:
     
defaultZone: http://localhost:7001/eureka

 

2.      完整部分

server:
 
port: 8001

mybatis:
 
config-location: classpath:mybatis/mybatis.cfg.xml        # mybatis配置文件所在路径
 
type-aliases-package: com.atguigu.springcloud.entities    # 所有Entity别名类所在包
  mapper-locations:
 
- classpath:mybatis/mapper/**/*.xml                       # mapper映射文件

spring:
  
application:
    name: microservicecloud-dept
  
datasource:
   
type: com.alibaba.druid.pool.DruidDataSource            # 当前数据源操作类型
   
driver-class-name: org.gjt.mm.mysql.Driver              # mysql驱动包
   
url: jdbc:mysql://localhost:3306/cloudDB01              # 数据库名称
   
username: root
   
password: kashowres
   
dbcp2:
     
min-idle: 5                                           # 数据库连接池的最小维持连接数
     
initial-size: 5                                      # 初始化连接数
     
max-total: 5                                          # 最大连接数
     
max-wait-millis: 200                                  # 等待连接获取的最大超时时间

eureka:
 
client:   #客户端注册进eureka服务列表中
    service-url:
     
defaultZone: http://localhost:7001/eureka

 

l  DeptProvider8001_App主启动类

package com.atguigu.springcloud;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.netflix.eureka.EnableEurekaClient;

@SpringBootApplication
@EnableEurekaClient //本服务启动后会自动注册进eureka服务中
public class DeptProvider8001_App {
   
public static void main(String[] args) {
   
    SpringApplication.run(DeptProvider8001_App.class,args);
   
}
}

l  测试

1.      先启动EurekaServer

2.      http://localhost:7001/

3.      微服务注册名配置说明

actuator与注册微服务信息完善

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

1.      当前问题

2.      修改microservicecloud-provider-dept-8001

YML

修改部分

eureka:
 
client:   #客户端注册进eureka服务列表中
    service-url:
     
defaultZone: http://localhost:7001/eureka
 
instance:
     
instance-id: microservicecloud-dept8001    #自定义服务名称信息

 

完整部分

server:
 
port: 8001

mybatis:
 
config-location: classpath:mybatis/mybatis.cfg.xml        # mybatis配置文件所在路径
 
type-aliases-package: com.atguigu.springcloud.entities    # 所有Entity别名类所在包
  mapper-locations:
 
- classpath:mybatis/mapper/**/*.xml                       # mapper映射文件

spring:
  
application:
    name: microservicecloud-dept
  
datasource:
   
type: com.alibaba.druid.pool.DruidDataSource            # 当前数据源操作类型
   
driver-class-name: org.gjt.mm.mysql.Driver              # mysql驱动包
   
url: jdbc:mysql://localhost:3306/cloudDB01              # 数据库名称
   
username: root
   
password: kashowres
   
dbcp2:
     
min-idle: 5                                           # 数据库连接池的最小维持连接数
     
initial-size: 5                                      # 初始化连接数
     
max-total: 5                                          # 最大连接数
     
max-wait-millis: 200                                  # 等待连接获取的最大超时时间

eureka:
 
client:   #客户端注册进eureka服务列表中
    service-url:
     
defaultZone: http://localhost:7001/eureka
 
instance:
     
instance-id: microservicecloud-dept8001    #自定义服务名称信息

 

3.      修改之后

l  访问信息有IP信息提示

1.      当前问题:没有IP提示

2.      修改microservicecloud-provider-dept-8001

YML

修改部分

eureka:
  client:   #客户端注册进eureka服务列表中
    service-url:
      defaultZone: http://localhost:7001/eureka
  instance:
      instance-id: microservicecloud-dept8001    #自定义服务名称信息
      prefer-ip-address: true     #访问路径可以显示IP地址

 

         完整部分

server:
  port: 8001

mybatis:
  config-location: classpath:mybatis/mybatis.cfg.xml        # mybatis配置文件所在路径
  type-aliases-package: com.atguigu.springcloud.entities    # 所有Entity别名类所在包
  mapper-locations:
  - classpath:mybatis/mapper/**/*.xml                       # mapper映射文件

spring:
   application:
    name: microservicecloud-dept
   datasource:
    type: com.alibaba.druid.pool.DruidDataSource            # 当前数据源操作类型
    driver-class-name: org.gjt.mm.mysql.Driver              # mysql驱动包
    url: jdbc:mysql://localhost:3306/cloudDB01              # 数据库名称
    username: root
    password: kashowres
    dbcp2:
      min-idle: 5                                           # 数据库连接池的最小维持连接数
      initial-size: 5                                       # 初始化连接数
      max-total: 5                                          # 最大连接数
      max-wait-millis: 200                                  # 等待连接获取的最大超时时间

eureka:
  client:   #客户端注册进eureka服务列表中
    service-url:
      defaultZone: http://localhost:7001/eureka
  instance:
      instance-id: microservicecloud-dept8001    #自定义服务名称信息
      prefer-ip-address: true     #访问路径可以显示IP地址

3.       


l  微服务info内容详细信息

1.      当前问题

超链接点击服务报告ErroPage

2.      修改microservicecloud-provider-dept-8001

POM

修改部分

<!-- actuator监控信息完善 -->
<dependency>
   <groupId>org.springframework.boot</groupId>
   <artifactId>spring-boot-starter-actuator</artifactId>
</dependency>

 

完整部分

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <parent>
        <artifactId>microservicecloud</artifactId>
        <groupId>com.atguigu.springcloud</groupId>
        <version>1.0-SNAPSHOT</version>
    </parent>
    <modelVersion>4.0.0</modelVersion>

    <artifactId>microservicecloud-provider-dept-8001</artifactId>

    <dependencies>
        <!-- 引入自己定义的api通用包,可以使用Dept部门Entity -->
        <dependency>
            <groupId>com.atguigu.springcloud</groupId>
            <artifactId>microservicecloud-api</artifactId>
            <version>${project.version}</version>
        </dependency>
        <!-- actuator监控信息完善 -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-actuator</artifactId>
        </dependency>
        <!--将微服务provider注册进eureka-->
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-eureka</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-config</artifactId>
        </dependency>
        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
        </dependency>
        <!-- mysql驱动包 -->
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
        </dependency>
        <!-- 连接池 -->
        <dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>druid</artifactId>
        </dependency>
        <!-- 日志 -->
        <dependency>
            <groupId>ch.qos.logback</groupId>
            <artifactId>logback-core</artifactId>
        </dependency>
        <!-- mybatis的整合 -->
        <dependency>
            <groupId>org.mybatis.spring.boot</groupId>
            <artifactId>mybatis-spring-boot-starter</artifactId>
        </dependency>
        <!-- boot的jetty 内置tomcat插件 -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-jetty</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
        </dependency>
        <!-- 修改后立即生效,热部署 -->
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>springloaded</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-devtools</artifactId>
        </dependency>
    </dependencies>

</project>

 

3.      总父工程microservicecloud修改pom.xml添加构建build信息

POM

修改部分

<build>
    <finalName>microservicecloud</finalName>
    <resources>
        <resource>
            <directory>src/main/resources</directory>
            <filtering>true</filtering>
        </resource>
    </resources>
    <plugins>
        <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-resources-plugin</artifactId>
            <configuration>
                <delimiters>
                    <delimit>$</delimit>
                </delimiters>
            </configuration>
        </plugin>
    </plugins>
</build>

 

完整部分

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <groupId>com.atguigu.springcloud</groupId>
    <artifactId>microservicecloud</artifactId>
    <version>1.0-SNAPSHOT</version>
    <packaging>pom</packaging>

    <properties>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        <maven.compiler.source>1.8</maven.compiler.source>
        <maven.compiler.target>1.8</maven.compiler.target>
        <junit.version>4.12</junit.version>
        <log4j.version>1.2.17</log4j.version>
        <lombok.version>1.16.18</lombok.version>
    </properties>

    <dependencyManagement>
        <dependencies>
            <dependency>
                <groupId>org.springframework.cloud</groupId>
                <artifactId>spring-cloud-dependencies</artifactId>
                <version>Dalston.SR1</version>
                <type>pom</type>
                <scope>import</scope>
            </dependency>
            <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-dependencies</artifactId>
                <version>1.5.9.RELEASE</version>
                <type>pom</type>
                <scope>import</scope>
            </dependency>
            <dependency>
                <groupId>mysql</groupId>
                <artifactId>mysql-connector-java</artifactId>
                <version>5.0.4</version>
            </dependency>
            <dependency>
                <groupId>com.alibaba</groupId>
                <artifactId>druid</artifactId>
                <version>1.0.31</version>
            </dependency>
            <dependency>
                <groupId>org.mybatis.spring.boot</groupId>
                <artifactId>mybatis-spring-boot-starter</artifactId>
                <version>1.3.0</version>
            </dependency>
            <dependency>
                <groupId>ch.qos.logback</groupId>
                <artifactId>logback-core</artifactId>
                <version>1.2.3</version>
            </dependency>
            <dependency>
                <groupId>junit</groupId>
                <artifactId>junit</artifactId>
                <version>${junit.version}</version>
                <scope>test</scope>
            </dependency>
            <dependency>
                <groupId>log4j</groupId>
                <artifactId>log4j</artifactId>
                <version>${log4j.version}</version>
            </dependency>
        </dependencies>
    </dependencyManagement>

    <!--微服务info内容详细信息-->
    <build>
        <finalName>microservicecloud</finalName>
        <resources>
            <resource>
                <directory>src/main/resources</directory>
                <filtering>true</filtering>
            </resource>
        </resources>
        <plugins>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-resources-plugin</artifactId>
                <configuration>
                    <delimiters>
                        <delimit>$</delimit>
                    </delimiters>
                </configuration>
            </plugin>
        </plugins>
    </build>

    <modules>
        <module>microservicecloud-api</module>
        <module>microservicecloud-provider-dept-8001</module>
        <module>microservicecloud-consumer-dept-80</module>
        <module>microservicecloud-eureka-7001</module>
    </modules>

</project>

 

4.      修改microservicecloud-provider-dept-8001

YML

修改部分

info:     #微服务info内容详细信息
  app.name: atguigu-microservicecloud
  company.name: www.atguigu.com
  build.artifactId: $project.artifactId$
  build.version: $project.version$

 

完整部分

server:
  port: 8001

mybatis:
  config-location: classpath:mybatis/mybatis.cfg.xml        # mybatis配置文件所在路径
  type-aliases-package: com.atguigu.springcloud.entities    # 所有Entity别名类所在包
  mapper-locations:
  - classpath:mybatis/mapper/**/*.xml                       # mapper映射文件

spring:
   application:
    name: microservicecloud-dept
   datasource:
    type: com.alibaba.druid.pool.DruidDataSource            # 当前数据源操作类型
    driver-class-name: org.gjt.mm.mysql.Driver              # mysql驱动包
    url: jdbc:mysql://localhost:3306/cloudDB01              # 数据库名称
    username: root
    password: kashowres
    dbcp2:
      min-idle: 5                                           # 数据库连接池的最小维持连接数
      initial-size: 5                                       # 初始化连接数
      max-total: 5                                          # 最大连接数
      max-wait-millis: 200                                  # 等待连接获取的最大超时时间

eureka:
  client:   #客户端注册进eureka服务列表中
    service-url:
      defaultZone: http://localhost:7001/eureka
  instance:
      instance-id: microservicecloud-dept8001    #自定义服务名称信息
      prefer-ip-address: true     #访问路径可以显示IP地址

info:     #微服务info内容详细信息
  app.name: atguigu-microservicecloud
  company.name: www.atguigu.com
  build.artifactId: $project.artifactId$
  build.version: $project.version$

eureka自我保护

l  演示Case

什么是自我保护模式?

 

默认情况下,如果EurekaServer在一定时间内没有接收到某个微服务实例的心跳,EurekaServer将会注销该实例(默认90秒)。但是当网络分区故障时,微服务在EurekaServer之间无法正常通信,以上行为可能变得非常危险了——因为微服务本身其实是健康的,此时不应该注销这个微服务。Eureka通过“自我保护模式”来解决这个问题——当EurekaServer节点在短时间内丢失过多客户端(可能发生了网络分区故障),那么这个节点就会进入自我保护模式。一旦进入该模式,EurekaServer就会保护服务注册表中的信息,不再删除服务注册表中的数据(也就是不会注销任何服务)。当网络故障恢复后,该EurekaServer节点会自动退出自我保护模式。

 

在自我保护模式中,Eureka Server会保护服务注册表中的信息,不再注销任何服务实例。当它收到的心跳数重新恢复到阈值以上时,该Eureka Server节点就会自动退出保护模式,它的设计哲学就是宁可保留错误的服务注册信息,也不盲目注销任何可能健康的服务实例。一句话讲解:好死不如赖活着

 

综上,自我保护模式是一种应对网络异常的安全保护措施。它的架构缺哲学是宁可同时保留所有微服务(健康的微服务和不健康的微服务都会保留),也不盲目注销任何健康的微服务。使用自我保护模式,可以让Eureka集群更加的健壮、稳定。

 

在Spring Cloud中,可以使用eureka.server. enable-self-preservation = false 禁用自我保护模式。

 

l  故障现象

l  导致原因

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

microservicecloud-provider-dept-8001 服务发现Disovery

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

 

l  修改microservicecloud-provider-dept-8001工程的DeptController

 

@Autowired
private DiscoveryClient discoveryClient;

 

@RequestMapping(value = "/dept/discovery",method = RequestMethod.GET)
public Object discovery(){
   
List <String> list= discoveryClient.getServices();
   
System.out.println("************"+list);

   
List <ServiceInstance> serviceInstances= discoveryClient.getInstances("MICROSERVICECLOUD-DEPT");
   
for (ServiceInstance instance:serviceInstances) {
       
System.out.println(instance.getServiceId()+"\t"+instance.getPort()+"\t"+instance.getUri());
   
}
    return this.discoveryClient;
}

 

l  DeptProvider8001_App主启动类

@EnableDiscoveryClient      //服务发现
public class DeptProvider8001_App {
    public static void main(String[] args) {
        SpringApplication.run(DeptProvider8001_App.class,args);
    }
}

 

l  自测

1.      先要启动EurekaServer

2.      再启动DeptProvider8001_App主启动类,需要稍等一会儿

3.      http://localhost:8001/dept/discovery


l  修改microservicecloud-consumer-dept-80工程的DeptController_Consmer

//测试@EnableDiscoveryClient,消费端可以调用服务实现
@RequestMapping(value = "/consumer/dept/discovery")
public Object discovery(){
    return  restTemplate.getForObject(REST_URL_PREFIX+"/dept/discovery",Object.class);
}

 5.4 集群配置

l  原理说明

l  新建microservicecloud-eureka-7002/microservicecloud-eureka-7003

l  按照 7001为模板粘贴POM

l  修改7002和7003的主启动类

l  修改映射配置

1.      找到C:\Windows\System32\drivers\etc路径下的hosts文件

2.      修改映射配置添加进hosts文件

l  3台eureka服务器的yml配置

1.      microservicecloud-eureka-7001配置

server:
  port: 7001

eureka:
  instance:
    #hostname: localhost   #eureka服务端的实例名称
    hostname: eureka7001.com   #eureka服务端的实例名称
  client:
    register-with-eureka: false    #flase表示不向注册中心注册自己
    fetch-registry: false    #flase表示自己端就是注册中心,我的职责就是维护服务实例,并不需要检索服务
    service-url:
      #单机 defaultZone: http://${eureka.instance.hostname}:${server.port}/eureka/  #设置与Eureka Server交互的地址查询服务和注册服务都需要依赖这个地址
      defaultZone: http://eureka7002.com:7002/eureka/,http://eureka7003.com:7003/eureka/
server:
#    enable-self-preservation: false   #禁用自我保护模式。禁用自我保护模式    不推荐使用

 

2.      microservicecloud-eureka-7002配置

server:
  port: 7002

eureka:
  instance:
    #hostname: localhost   #eureka服务端的实例名称
    hostname: eureka7002.com   #eureka服务端的实例名称
  client:
    register-with-eureka: false    #flase表示不向注册中心注册自己
    fetch-registry: false    #flase表示自己端就是注册中心,我的职责就是维护服务实例,并不需要检索服务
    service-url:
      #单机 defaultZone: http://${eureka.instance.hostname}:${server.port}/eureka/  #设置与Eureka Server交互的地址查询服务和注册服务都需要依赖这个地址
      defaultZone: http://eureka7001.com:7001/eureka/,http://eureka7003.com:7003/eureka/
server:
#    enable-self-preservation: false   #禁用自我保护模式。禁用自我保护模式    不推荐使用

 

3.      microservicecloud-eureka-7003配置

server:
  port: 7003

eureka:
  instance:
    #hostname: localhost   #eureka服务端的实例名称
    hostname: eureka7003.com   #eureka服务端的实例名称
  client:
    register-with-eureka: false    #flase表示不向注册中心注册自己
    fetch-registry: false    #flase表示自己端就是注册中心,我的职责就是维护服务实例,并不需要检索服务
    service-url:
      #单机 defaultZone: http://${eureka.instance.hostname}:${server.port}/eureka/  #设置与Eureka Server交互的地址查询服务和注册服务都需要依赖这个地址
      defaultZone: http://eureka7001.com:7001/eureka/,http://eureka7002.com:7002/eureka/
server:
#    enable-self-preservation: false   #禁用自我保护模式。禁用自我保护模式    不推荐使用

 

l  microservicecloud-provider-dept-8001微服务发布到上面3台eureka集群配置中

5.5 作为服务注册中心,Eureka比Zookeeper好在那里

l  RDBMS (mysql/oracle/sqlServer) ====》ACID

1.      A(Atomicity)    原子性

原子性很容易理解,也就是说事务里的所有操作要么全部做完,要么都不做,事务成功的条件是事务里的所有操作都成功,只要有一个操作失败,整个事务都失败,需要回滚。比如银行转账,从A账户转100元至B账户,分为两个步骤:1)从A账户取100元;2)存入100元至B账户。这两步要么一起完成,要么一起不完成,如果只完成第一步,第二步失败,钱会莫名其妙少了100元。

2.      C(Consistency)          一致性

一致性也比较容易理解,也就是说数据库要一直处于一致的状态,事务的运行不会改变数据库原本的一致性约束。

3.      I(Isolation)       独立性

所谓的独立性是指并发的事务之间不会互相影响,如果一个事务要访问的数据正在被另一个事务修改,只要另一个未提交,它所访问的数据就不受未提交的影响。比如现有个交易从A账户转100元至B账户,在这个交易还未完成的情况下,如果此时B查询自己的账户,是看不到新增加的100元的

4.      D(Durability)    持久性

持久性指一旦事务提交后,它所做的修改将会永久的保存在数据库上,即使出现宕机也不会丢失

l  NOSQL (redis/monbdb) ====》 CAP

         C:Consistency(强一致性)

         A:Availability   (可用性)

         P:Partitiontolerance (分区容错性)

         CAP理论的核心是:一个分布式系统不可能同时很好的满足一致性,可用性和分区容错这三个需求,因此CAP原理将NoSQL数据库分成了满足CA原则、滞CP原则和满足AP原则三大类:

         CA- 单点集群,满足一致性,可用性的系统,通常在可扩展性上不太强大

         CP- 满足致性,分区容忍的系统,通常性能不是特别高

         AP- 满足可用性,分区忍让的系统,通常可能对一致性要求低一些。

 

l  CAP的3进2

CAP理论就是说在分布式存储系统中,最多只能实现上面的两点。而由于当前的网络硬件肯定会出现延迟丢包等问题,所以

分区容忍性是我们必须需要实现的

所以我们只能在一致性可用性之间权衡,没有NoSQL系统能同时保证这三点。

C:强一致性         A:高可用性             P:分布式容忍性

CA    传统Oracle数据库

AP    大多数网站架构的选择

CP    RedisMongodb

注意:分布式架构的时候必须做出取舍

 

作为服务注册中心,Eureka比Zookeeper好在哪里

著名的CAP理论指出,一个分布式系统不可能同时满足C(一致性)、A(可用性)和P(分区容错性)。由于分区容错性P在是分布式系统中必须要保证的,因此我们只能在A和C之间进行权衡。

Zookeeper保证的是CP,

Eureka则是AP

 

l  Zookeeper保证CP

         当向注册中心查询服务列表时,我们可以容忍注册中心返回的是几分钟以前的注册信息,但不能接受服务直接down掉不可用。也就是说,服务注册功能对可用性的要求要高于一致性。但是zk会出现这样一种情况,当master节点因为网络故障与其他节点失去联系时,剩余节点会重新进行leader选举。问题在于,选举leader的时间太长,30 ~ 120s,且选举期间整个zk集群都是不可用的,这就导致在选举期间注册服务瘫痪。在云部署的环境下,因网络问题使得zk集群失去master节点是较大概率会发生的事,虽然服务能够最终恢复,但是漫长的选举时间导致的注册长期不可用是不能容忍的。

 

l  Eureka保证AP

         Eurekar看明白了这一点,因此在设计时就优先保证可用性。Eureka各个节点都是平等的,几个节点挂掉不会影响正常节点的工作,剩余的节点依然可以提供注册和查询服务。而Eureka的客户端在向某个Eureka注册或时如果发现连接失败,则会自动切换至其它节点,只要有一台Eureka还在,就能保证注册服务可用(保证可用性),只不过查到的信息可能不是最新的(不保证强一致性)。除此之外,Eureka还有一种自我保护机制,如果在15分钟内超过85%的节点都没有正常的心跳,那么Eureka就认为客户端与注册中心出现了网络故障,此时会出现以下几钟情况:

1.      Eureka不再从注册列表中移除因为长时间没收到心跳而应该过期的服务

2.      Eureka仍然能够接受新服务的注册和查询请求,但是不会被同步其它节点上(即保证当前节点依然可用)

3.      当网络稳定时,当前实例的新的注册信息会被同步到其它节点中

        

因此,Eureka可以很好的应对网络故障导致部分节点失去联系的情况,而不会像Zookeeper那样使整个注册瘫痪。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值