SpringCloud之Eureka(服务注册和发现)

  • Eureka 是一个基于REST的服务,用于服务的的注册与发现;
  • Eureka采用C-S的设计架构,Eureka Server作为服务注册功能的服务器,它是服务注册中心;
  • Eureka包含两个组件:Eureka Server 和 Eureka Client
    • Eureka Server提供服务注册和发现;
    • Eureka Client是一个java客户端;

- Eureka是一个基于REST的服务,用于定位服务,以实现云端中间层服务发现和故障转移。
- Eureka主管服务注册与发现,在微服务中,以后了这两者,只需要使用服务的标识符(==就是那个在每个服务的yml文件中取得服务名称==),就可以访问到服务,不需要修改服务调用的配置文件

- Eureka遵循AP原则(高可用,分区容错性),因为使用了自我保护机制所以保证了高可用

- 两大组件:Eureka Server(提供注册服务)、 Eureka Client(JAVA客户端,负责发送心跳)
- 系统中的其他微服务使用Eureka客户端连接到Eureka服务端维持心跳连接(即注册)。SpringCloud的其他模块可以通过Eureka Server 来发现系统中的微服务并加以调用

三大角色
    Eureka Server提供服务注册和发现;
    Service Provider服务提供方将自身服务注册到Eureka,从而使服务消费方能够找到;

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

## SpringCloud添加组件的基本套路

1. 新增这个组件的maven坐标
2. 在启动类上面标注启动该组件(一般来说是@EnableXXXXX)
3. 编写业务逻辑代码

Eureka 服务注册中心Module(spring-cloud-eureka-7001)

<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>
  <parent>
    <groupId>com.zhou</groupId>
    <artifactId>spring-cloud</artifactId>
    <version>0.0.1-SNAPSHOT</version>
  </parent>
  <artifactId>spring-cloud-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>

// application.yml

server:
  port: 7001

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

// EurekaServer7001_App

==注意:要在类前加@EnableEurekaServer标注==

@SpringBootApplication
@EnableEurekaServer  // EurekaServer 服务器端启动类,接收其他微服务注册进来
public class EurekaServer7001_App {

    public static void main(String[] args) {
        SpringApplication.run(EurekaServer7001_App.class, args);
    }
}
// 测试:// 访问: http://localhost:7001


将已有的部门微服务注册进eureka服务中心(spring-cloud-provider-dept-8001)

// 修改spring-cloud-provider-dept-8001

// pom.xml 增加

<!-- 将微服务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>

// application.yml 增加

- 在application.yml中增加以内容,将客户端注册到服务列表内

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

// DeptProvider8001_App 主启动类

- 增加@EnableEurekaClient注解

@SpringBootApplication
@EnableEurekaClient // 本服务启动后,自动注册进eureka服务中
public class DeptProvider8001_App {

    public static void main(String[] args) {
        SpringApplication.run(DeptProvider8001_App.class, args);
    }
}
// 测试:// 先要启动 EurekaServer,然后启动 DeptProvicer8001_App
// 访问:http://localhost:7001/, 他的微服务名字就是之前在yml文件中配置的名字


actuator 与注册微服务信息完善
    主机映射名称修改
    访问信息有IP信息提示

    微服务info内容详细信息

主机机名称与服务名称的修改

- 修改服务名称,在yml中eureka节点下添加如下内容:

修改之前:


修改之后:


// 主机映射名称修改
// 修改spring-cloud-provider-dept-8001

// application.xml

eureka:
  client: # 客户端注册进eureka服务列表内
    service-url:
      defaultZone: http://localhost:7001/eureka
  instance:
    instance-id: spring-cloud-dept8001     # 主机映射名称
// 访问信息有IP信息提示
// 修改spring-cloud-provider-dept-8001

// application.xml

eureka:
  client: # 客户端注册进eureka服务列表内
    service-url:
      defaultZone: http://localhost:7001/eureka
  instance:
    instance-id: microservicecloud-dept8001     # 主机映射名称
    prefer-ip-address: true                     # 访问路径可以显示IP地址


// 微服务info内容详细信息

在查看Eureka时点击进入某个微服务的info时,能给查看者一些必要的信息,可以帮助查看者快速的了解该微服务,开发中十分有意义

// 修改spring-cloud-provider-dept-8001

// pom.xml

1. ==当前工程==添加依赖:

<!-- actutator 监控信息完善 -->

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

2. ==总的父工程==的build节点下添加如下内容

// 修改父工程 spring-cloud
// pom.xml

<build>
        <finalName>spring-ecloud</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>

3. 在==当前工程== 的application.yml文件添加回显信息

// 修改spring-cloud-provider-dept-8001
// application.yml

info:
  app.name: zhou-microservicecloud
  company.name: www.google.com
  build.artifactId: $project.artifactId$
  build.version: $project.version$

Eureka 自我保护机制


Eureka的自我保护机制主要是为了网络异常时保持高可用设计的,当在Eureka中注册的微服务超过设定是时间内(默认90秒)没有向Eureka服务端发送心跳,该微服务会进入自我保护模式。在自我保护模式中,Eureka会保护服务注册表中的信息,不会注销任何服务实例,直至收到的心跳数恢复至阈值以上,该微服务退出自我保护模式

好死不如赖活:Eureka的设计哲学是宁可保留错误的服务信息,也不盲目注销可能健康的服务。所以异常的服务不会被注销,而是进入了自我保护模式

自我保护模式的开关

在Eureka Server模块下的yml文件中添加配置信息即可,true表示打开自我保护模式;false表示关闭自我保护模式(不推荐)

// 修改 microservicecloud-eureka-7001
// 将自我保护机制关闭(不推荐)
// application.yml
eureka:
  server:
    enable-self-preservation: false
Eureka的服务发现
#### 介绍
系统中的微服务可以通过Eureka的服务发现去获得在Eureka中注册的服务的信息,这是一个对外暴露的接口

使用方法(provider中)

// 修改 microservicecloud-provider-dept-8001

1. 注入DiscoveryClient 对象(spring包下的),在controller方法中获取

@RestController
public class DeptController {

    @Autowired
    private DeptService deptService;

    @Autowired
    private DiscoveryClient client;

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

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

2. 在主启动类中加入@EnableDiscoveryClient注解

@SpringBootApplication
@EnableEurekaClient // 本服务启动后,自动注册进eureka服务中
@EnableDiscoveryClient  // 服务发现
public class DeptProvider8001_App {

    public static void main(String[] args) {
        SpringApplication.run(DeptProvider8001_App.class, args);
    }
}

使用方法(consumer中)

在controller方法中使用restTemplate对象调用provider中暴露的URL 并获得返回对象即可

// 修改 microservicecloud-consumer-dept-80 工程的 DeptController Consumer

@RequestMapping(value="/consumer/dept/discovery")
public Object discovery() {
    return restTemplate.getForObject(REST_URL_PREFIX+"/dept/discovery", Object.class);
}
Eureka的集群配置

集群就是在不同的机器上配置相同的服务来构建要一个大的运算整体
#### 实现集群
1. 新建N个Eureka Server模块
2. 每个模块的pom.xml中加入与单个Eureka Server相同的依赖
3. 每个模块加入主程序(记得加@EnableEurekaServer注解)

4. 修改hosts文件(Win7的路径是C:\Windows\System32\drivers\etc)

// 新建microservicecloud-eureka-7002/microservicecloud-eureka-7003
// 按照7001为模板粘贴POM
// 修改7002和7003的主启动类
// 修改映射配置 hosts
127.0.0.1 eureka7001.com
127.0.0.1 eureka7002.com
127.0.0.1 eureka7003.com
修改Eureka Server模块的application.yml文件,加入集群,主要修改两个地方:
- hostname:修改为hosts文件中映射的地址
- service-url下的defaultZone节点:填入集群中另外的server服务端的地址

// 7001 application.yml
server:
  port: 7001

eureka:
  instance:
    hostname: eureka7001.com  #eureka服务端的实例名称
  client:
    register-with-eureka: false
    fetch-registry: false
    service-url:
       defaultZone: http://eureka7002.com:7002/eureka/,http://eureka7003.com:7003/eureka/

// 7002 application.yml
server:
  port: 7002

eureka:
  instance:
    hostname: eureka7002.com  #eureka服务端的实例名称
  client:
    register-with-eureka: false
    fetch-registry: false
    service-url:
       defaultZone: http://eureka7001.com:7001/eureka/,http://eureka7003.com:7003/eureka/
修改Eureka Client模块的application.yml文件,使其向集群注册服务

- service-url下的defaultZone节点:填入集群中需要向其注册server服务端的地址

 ==注:defaultZone中eureka/后缀是必须的,如果删除,Server类不会报错,但是Client注册时会报404错误==

// microservicecloud-provider-dept-8001
// 微服务发布到3台eureka集群配置中, application.yml
eureka:
  client: # 客户端注册进eureka服务列表内
    service-url:
      defaultZone: http://eureka7001.com:7001/eureka,http://eureka7002.com:7002/eureka,http://eureka7003.com:7003/eureka
// 测试访问:
// http://eureka7001.com:7001
// http://eureka7002.com:7002
// http://eureka7003.com:7003

### Eureka与Zookeeper对比

#### CAP设计原则不同

Eureka遵守AP,Zookeeper遵守CP(C:强一致性,A:高可用,P:分区容错性,三者只能选其二,高并发下P必选)

网络波动下两者的处理对比


#### 结论
Eureka可以很好的应对网络故障导致部分节点失去连接的情况,而不会像zookeeper那样导致整个注册服务系统的瘫痪

猜你喜欢

转载自blog.csdn.net/qq_35508033/article/details/80763432