SpringCloud 学习(二)Eureka

3. Netflix.Eureka

3.1 简介

  • Eureka( [juˈriːkə] )遵循 AP 原则。
  • Eureka 是 Netflix 的核心模块,基于 REST 实现云端中间层服务发现和故障转移,用于定位服务。
  • 服务注册与发现使 consumer 不需要修改服务调用的配置文件,只需要使用服务的标识符,就可以访问服务。类似于 Dubbo 的注册中心,如 zookeeper。

3.2 架构

3.3 环境搭建

(1) 创建一个 maven 模块作为 eureka 注册中心

springcloud-eureka-7001

● 导入依赖
<artifactId>springcloud-eureka-7001</artifactId>

<dependencies>
    <!-- https://mvnrepository.com/artifact/org.springframework.cloud/spring-cloud-starter-eureka-server -->
    <dependency>
        <groupId>org.springframework.cloud</groupId>
        <artifactId>spring-cloud-starter-eureka-server</artifactId>
        <version>1.4.6.RELEASE</version>
    </dependency>
    <!--热部署工具-->
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-devtools</artifactId>
    </dependency>
</dependencies>
● 编写配置文件
server:
  port: 7001

eureka:
  instance:
    hostname: localhost # Eureka 服务端实例名
  client:
    register-with-eureka: false # 是否向注册中心注册
    fetch-registry: false # false 表示本身为注册中心
    service-url: # 设置服务的 url(监控页面)
      defaultZone: http://${eureka.instance.hostname}:${server.port}/eureka/
● 编写主类
// 启动后访问 http://localhost:7001/
@SpringBootApplication
// 标识为 eureka 服务端,可接受其他服务的注册
@EnableEurekaServer
public class EurekaServer_7001 {
    public static void main(String[] args) {
        SpringApplication.run(EurekaServer_7001.class, args);
    }
}

在这里插入图片描述

3.4 服务注册

将 springcloud-provider-dept-8001 服务注册到 eureka 注册中心

(1) 导入依赖

<!-- https://mvnrepository.com/artifact/org.springframework.cloud/spring-cloud-starter-eureka -->
<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-eureka</artifactId>
    <version>1.4.6.RELEASE</version>
</dependency>

(2) 配置 eureka 注册服务的地址

# eureka
eureka:
  client:
    service-url:
      # 注册中心的地址
      defaultZone: http://localhost:7001/eureka/
  instance:
    # 修改服务实例描述
    instance-id: springcloud-provider-dept8001

(3) 启动类开启 eureka 客户端注册

// 服务启动后注册到 eureka 注册中心
@EnableEurekaClient
@SpringBootApplication
public class DeptProvider_8001 {
    public static void main(String[] args) {
        SpringApplication.run(DeptProvider_8001.class, args);
    }
}

在这里插入图片描述

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 保护机制

某微服务不可用时,eureka 不清理其保存在 注册中心的信息,防止微服务本身没有问题的情况下,服务信息被清理。

(4) 完善监控信息

● 导入依赖
<!--actuator-->
<!--完善监控信息-->
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
● 添加配置
# info
info:
  app.name: why-springcloud
  company.name: blog.why.com

在这里插入图片描述

在这里插入图片描述

(5) 服务发现

调整 springcloud-provider-dept-8001 服务

● 添加控制器
@Autowired
    // org.springframework.cloud.client.discovery.DiscoveryClient
    private DiscoveryClient discoveryClient;

/**
 * 发现并获取微服务信息
 * @return
 */
@RequestMapping("/dept/discovery")
public Object discovery() {
    // 获取微服务列表的清单
    List<String> services = discoveryClient.getServices();
    System.out.println("discovery services => " + services);

    // 通过 ApplicationName 获取服务信息
    List<ServiceInstance> instances = discoveryClient.getInstances("SPRINGCLOUD-PROVIDER-DEPT");
    for (ServiceInstance instance : instances) {
        System.out.println(
                "host => " + instance.getHost() + "\n" +
                "port => " + instance.getPort() + "\n" +
                "url => " + instance.getUri() + "\n" +
                "serviceId = > " + instance.getServiceId()
        );
    }
    return this.discoveryClient;
}
● 主类添加服务发现注解
// 服务启动后注册到 eureka 注册中心
@EnableEurekaClient
// 服务发现
@EnableDiscoveryClient
@SpringBootApplication
public class DeptProvider_8001 {
    public static void main(String[] args) {
        SpringApplication.run(DeptProvider_8001.class, args);
    }
}
● 访问控制器

http://localhost:8001/dept/discovery

{"discoveryClients":[{"services":["springcloud-provider-dept"],"order":0},{"services":[],"order":0}],"services":["springcloud-provider-dept"],"order":0}

在这里插入图片描述

3.5 模拟集群环境配置

(1) 添加微服务

● 创建两个 maven 模块作为集群

springcloud-eureka-7002
springcloud-eureka-7001
springcloud-eureka-7003

在这里插入图片描述

● 导入依赖
<dependencies>
    <!-- https://mvnrepository.com/artifact/org.springframework.cloud/spring-cloud-starter-eureka-server -->
    <dependency>
        <groupId>org.springframework.cloud</groupId>
        <artifactId>spring-cloud-starter-eureka-server</artifactId>
        <version>1.4.6.RELEASE</version>
    </dependency>
    <!--热部署工具-->
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-devtools</artifactId>
    </dependency>
</dependencies>
● 修改配置文件
server:
  port: 7002

eureka:
  instance:
    # Eureka 服务端实例名
    hostname: eureka7002.com
  client:
    # 是否向注册中心注册
    register-with-eureka: false
    # false 表示本身为注册中心
    fetch-registry: false
    # 设置服务的 url(监控页面)
    service-url:
      defaultZone: http://eureka7001.com:7001/eureka/,http://eureka7003.com:7003/eureka/
server:
  port: 7003

eureka:
  instance:
    # Eureka 服务端实例名
    hostname: eureka7003.com
  client:
    # 是否向注册中心注册
    register-with-eureka: false
    # false 表示本身为注册中心
    fetch-registry: false
    # 设置服务的 url(监控页面)
    service-url:
      defaultZone: http://eureka7001.com:7001/eureka/,http://eureka7002.com:7002/eureka/
● 创建启动类
// 启动后访问 http://localhost:7002/
@SpringBootApplication
// 标识为 eureka 服务端,可接受其他服务的注册
@EnableEurekaServer
public class EurekaServer_7002 {
    public static void main(String[] args) {
        SpringApplication.run(EurekaServer_7002.class, args);
    }
}
// 启动后访问 http://localhost:7003/
@SpringBootApplication
// 标识为 eureka 服务端,可接受其他服务的注册
@EnableEurekaServer
public class EurekaServer_7003 {
    public static void main(String[] args) {
        SpringApplication.run(EurekaServer_7003.class, args);
    }
}

(2) 配置域名映射(模拟多终端注册)

● 添加 hosts 配置
  • 路径:C:\Windows\System32\drivers\etc\hosts

  • 配置

    #Eureka
    127.0.0.1 eureka7001.com
    127.0.0.1 eureka7002.com
    127.0.0.1 eureka7003.com
    

(3) 注册服务

● 修改 8001 服务的 eureka 配置
# application.yml
# eureka
eureka:
  client:
    service-url:
      # 注册中心的地址
      # 将此服务注册到下面三个注册中心中
      defaultZone: http://localhost:7001/eureka/,http://localhost:7002/eureka/,http://localhost:7003/eureka/
  instance:
    # 修改服务实例描述
    instance-id: springcloud-provider-dept8001

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

3.6 CPA 原则及对比 zookeeper

(1) CPA 原则

  • “C”是指一致性,

    • 即当一个Process(过程)修改了某个数据后,其他Process读取这是数据是,得到的是更新后的数据,但并不是所有系统都 可以做到这一点。
    • 在一些并非严格要求一致性的系统中,后来的Process得到的数据可能还是修改之前的数据,或者需要等待一定时间后才能得到修改 之后的数据,这被成为“弱一致性”,最经典的应用就是DNS系统。当用户修改了DNS配置后,往往不会马上在全网更新,必定会有一个延迟,这个延迟被称为 “不一致窗口”,它的长度取决于系统的负载、冗余的个数等因素。
    • 对于某些系统而言,一旦写入,后面读取的一定是修改后的数据,如银行账户信息,这被称为 “强一致性”。
  • “A”是指可用性。

    • 即系统总是能够为用户提供连续的服务能力。
    • 当用户发出请求是,系统能给出响应(成功或者失败),而且是立即给出响应,而不是等待其他事情完成才响应。如果需要等待某件事情完成才响应,那么“可用性”就不存在了。
  • “P”是指容错性。

    • 任何一个分布式计算系统都是由多个节点组成的。在正常情况下,节点与节点之间的通信是正常的。但是在某些情况下,节点之间的通信会 断开,这种断开成为“Partition”。在分布式计算的实现中,Partition是很常见的,因为节点不可能永远不出故障,尤其是对于跨物理地区的 海量存储系统而言,而容错性则可以保证如果只是系统中的部分节点不可用,那么相关的操作仍旧能够正常完成。

参考: 分布式计算的重要原则——CPA理论_dq_cc的博客-CSDN博客

(2) 对比 zookeeper

  • CAP理论告诉我们,一个分布式系统不可能同时满足以下三种

一致性(C:Consistency)
可用性(A:Available)
分区容错性(P:Partition Tolerance)
​ 这三个基本需求,最多只能同时满足其中的两项,因为P是必须的,因此往往选择就在CP或者AP中。

  • 在此ZooKeeper保证的是CP

  • 分析:可用性(A:Available)

    • 不能保证每次服务请求的可用性。任何时刻对ZooKeeper的访问请求能得到一致的数据结果,同时系统对网络分割具备容错性;但是它不能保证每次服务请求的可用性(注:也就是在极端环境下,ZooKeeper可能会丢弃一些请求,消费者程序需要重新请求才能获得结果)。所以说,ZooKeeper不能保证服务可用性。

    • 进行leader选举时集群都是不可用。在使用ZooKeeper获取服务列表时,当master节点因为网络故障与其他节点失去联系时,剩余节点会重新进行leader选举。问题在于,选举leader的时间太长,30 ~ 120s, 且选举期间整个zk集群都是不可用的,这就导致在选举期间注册服务瘫痪,虽然服务能够最终恢复,但是漫长的选举时间导致的注册长期不可用是不能容忍的。所以说,ZooKeeper不能保证服务可用性。

参考: ZooKeeper和CAP理论及一致性原则_架构师专栏的博客-CSDN博客

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值