【SpringCloud(2)】微服务注册中心:Eureka、Zookeeper;CAP分析;服务注册与服务发现;单机/集群部署Eureka;连接注册中心

1. 什么是服务治理?

SpringCloud封装了Netfix开发的Eureka模块来实现服务治理

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

2. 什么是服务注册与发现

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

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

2.1 Eureka

2.1.1 Eureka Server提供服务注册服务

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

2.1.2 EurekaClient通过注册中心进行访问

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

3. Eureka实操

3.1 单机Eureka实现

在项目中,消费者和提供者需要引入jar包

xml 复制代码
<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
</dependency>

并在SpringBoot启动类添加**@EnableEurekaClient**注解

yaml需要配置Eureka的注册中心地址以及是否注册等确认信息

yaml 复制代码
########################### Eureka ##################################
eureka:
  client:
    register-with-eureka: true
    fetch-registry: true
    # 在server里,service-url直接填写地址,但在client中需要添加defaultZone
    service-url:
      defaultZone: http://localhost:7001/eureka
  • 需要一个新的模块来作为Eureka注册中心

在这个新模块中,需要引入jar包

xml 复制代码
<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-netflix-eureka-server</artifactId>
</dependency>

并在SpringBoot启动类上添加**@EnableEurekaServer**注解

yaml配置文件中

yaml 复制代码
server:
  port: 7001
eureka:
  instance:
    hostname: localhost # eureka服务端的实例名称
  client:
    fetch-registry: false # 不去检索服务
    register-with-eureka: false # 不向注册中注册自己
    # 设置Eurekaserve交互的地址查询服务和注册服务都需要依赖这个地址
    server-url: http://${eureka.instance.hostname}:${server.port}/eureka/

3.2 集群Eureka部署

准备两个或多个模块进行部署EurekaServer

当存在有多个时yaml文件必须一一对应上

  • Server7002
yaml 复制代码
server:
  port: 7002
eureka:
  instance:
    #hostname: localhost # eureka服务端的实例名称
    hostname: eureka7002.com # eureka集群
  client:
    fetch-registry: false # 不去检索服务
    register-with-eureka: false # 不向注册中注册自己
    # 设置Eurekaserve交互的地址查询服务和注册服务都需要依赖这个地址
    #server-url: http://${eureka.instance.hostname}:${server.port}/eureka/
    service-url:
      defaultZone: http://eureka7001.com:7001/eureka # eureka集群配置,需要集群其他内容
  • Server7001
yaml 复制代码
server:
  port: 7001
eureka:
  instance:
    #hostname: localhost # eureka服务端的实例名称
    hostname: eureka7001.com # eureka集群
  client:
    fetch-registry: false # 不去检索服务
    register-with-eureka: false # 不向注册中注册自己
    # 设置Eurekaserve交互的地址查询服务和注册服务都需要依赖这个地址
    #server-url: http://${eureka.instance.hostname}:${server.port}/eureka/
    service-url:
      defaultZone: http://eureka7002.com:7002/eureka # eureka集群配置,需要集群其他内容

在提供者和消费者上,yaml文件的Eureka地址也都需要一一添加

yaml 复制代码
########################### Eureka ##################################
eureka:
  client:
    register-with-eureka: true
    fetch-registry: true
    # 在server里,service-url直接填写地址,但在client中需要添加defaultZone
    service-url:
      defaultZone: http://localhost:7001/eureka,http://localhost:7002/eureka # Eureka集群

4. 提供者集群部署

为了更大的提高算力以及资源分配,多个提供者还是有必要的。

两个提供者,一个8001,一个8002;配置一样,除了端口号,需要更改的只有端口号

消费者80需要更改部分较多

  1. 在指定路径的Controller中,需要重新定义地址

    java 复制代码
    //    public static final String PAYMNT_URL = "http://localhost:8001";// 单机
    /**
         * 按照集群来说明地址的话,需要按照Eureka中的注册服务名来作为地址
         * CLOUD-PAYMENT-SERVICE
         */
    public static final String PAYMNT_URL = "http://CLOUD-PAYMENT-SERVICE";// 集群

    在集群中,只需要填写提供者在Eureka的服务名

    请注意这里还不是完成,我们需要开启负载均衡技术,因为规定了地址后,Eureka不会帮你去找提供者来处理请求,如果不开启将会报错

  2. 需要在消费者ApplicatonContextConfig类中找到RestTemplate模板的获取点,添加上**@LoadBalanced**注解赋予RestTemplate模板负载均衡技术

    java 复制代码
    @Configuration
    public class ApplicatonContextConfig {
    
        /**
         * 获得RestTemplate;通过注解方式注入进IOC中
         *
         * @return
         */
        @Bean
        @LoadBalanced// 开启负载均衡
        public RestTemplate getRestTemplate() {
            return new RestTemplate();
        }
    }

5. 服务发现和Eureka自我保护

5.1 服务发现

  • 我们可用在提供者上设置服务发现,这样可以在Eureka中可以暴露提供者的信息
java 复制代码
import org.springframework.cloud.client.ServiceInstance;
import org.springframework.cloud.client.discovery.DiscoveryClient;

@Resource
private DiscoveryClient discoveryClient;// 将自身暴露出去

/**
     * 暴露关于自身服务的地址
     * @return
     */
@GetMapping("/discovery")
public Object discovery(){
    List<String> services = discoveryClient.getServices();
    for (String service : services) {
        log.info("******element"+service);
    }
    List<ServiceInstance> instances = discoveryClient.getInstances("CLOUD-PAYMENT-SERVICE");
    for (ServiceInstance instance : instances) {
        log.info(instance.getInstanceId()+" + "+instance.getHost()+" + "+instance.getPort()+" + "+instance.getUri());
    }
    return this.discoveryClient;
}

同时,再服务启动类上需要添加**@EnableEurekaClient**注解

5.2 Eureka自我保护

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

5.3 为什么会产生Eureka自我保护机制?

为了防止EurekaClient可以正常运行,但是与EurekaServer网络不通的情况下,EurekaServer不会立刻将EurekaClient服务剔除

5.4 什么是自我保护模式?

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

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

它的设计理念就是宁可保留错误的服务注册比信息,也不盲目注销任何可能健康的服务实例

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

5.5 关闭自我保护模式

修改提供者和注册中心的配置文件

  • 提供者:

    yaml 复制代码
    ########################### Eureka ##################################
    eureka:
      client:
        register-with-eureka: true
        fetch-registry: true
        # 在server里,service-url直接填写地址,但在client中需要添加defaultZone
        service-url:
          defaultZone: http://localhost:7001/eureka,http://localhost:7002/eureka
      instance:
        instance-id: payment8001
        prefer-ip-address: true
        # Eureka客户端向服务端发送心跳的时间间隔,单位为秒
        lease-renewal-interval-in-seconds: 1 # 一秒钟;默认30秒
        # Eureka服务器在收到最后一次心跳后等待时间上线,单位为秒(默认90秒),超时将删除服务
        lease-expiration-duration-in-seconds: 2
  • 注册中心

    yaml 复制代码
    server:
      port: 7002
    eureka:
      instance:
        #hostname: localhost # eureka服务端的实例名称
        hostname: eureka7002.com # eureka集群
      client:
        fetch-registry: false # 不去检索服务
        register-with-eureka: false # 不向注册中注册自己
        # 设置Eurekaserve交互的地址查询服务和注册服务都需要依赖这个地址
        #server-url: http://${eureka.instance.hostname}:${server.port}/eureka/
        service-url:
          defaultZone: http://eureka7001.com:7001/eureka # eureka集群配置,需要集群其他内容
     #########################################################################
      server:
        enable-self-preservation: false # 禁用自我保护模式
        eviction-interval-timer-in-ms: 20000

6. Zookeeper

yaml 复制代码
server:
  port: 8004

#### 连接zookeeper
spring:
  application:
    name: cloud-provider-payment
  cloud:
    zookeeper:
      connect-string: 192.168.21.128:2181 # zookeeper连接地址

其他配置与Eureka没有区别。

7. 注册中心的异同点:

组件名 语言 CAP 服务健康检查 对外暴露接口 SpringCloud集成
Eureka JAVA AP 可配支持 HTTP 集成
Consul GO CP 支持 HTTP/DNS 集成
Zookeeper JAVA CP 支持 客户端 集成
  • CAP:
    1. C ------ Consistency(强一致性性)
    2. A ------ Availability(可用性)
    3. P ------ Partition tolerance(分区容错性)

在CAP中,最多只能同时较好的满足两个需求,不是AP就是CP

CAP理论的核心是:一个分布式系统不可能同时很好的满足一致性、可用性、和分区容错性这三个需求

因此,根据CAP原理将NoSQL数据库分成了满足CA原则、满足CP原则和满足AP原则三大类

  1. CA ------ 单点集群,满足一致性,可用性的系统,通常在可扩展性不太强大
  2. CP ------ 满足一致性和分区容错性的系统,通信性能不是特别高
  3. AP ------ 满足可用性,分区容错性的系统,通常可能对一致性要求低一些

7.1 AP

7.2 CP

🥸🏏SpringCloud微服务专栏

  1. 【SpringCloud(1)】初识微服务架构:创建一个简单的微服务;java与Spring与微服务;初入RestTemplate

💕👉博客专栏

相关推荐
编织幻境的妖7 小时前
Zookeeper在大数据集群中的作用详解
大数据·分布式·zookeeper
眠りたいです8 小时前
基于脚手架微服务的视频点播系统-服务端开发部分(补充)文件子服务问题修正
c++·微服务·云原生·架构
是垚不是土9 小时前
基于Blackbox Exporter的网络服务黑盒监控体系实践
网络·数据库·安全·http·微服务·prometheus
Haooog9 小时前
微服务篇面试题(不定时更新)
微服务·面试·架构
2501_924064119 小时前
2025年微服务全链路性能瓶颈分析平台对比与最佳实践
微服务·云原生·性能优化·架构
mobº9 小时前
K8s 集群部署微服务 - DevOps(二)
微服务·kubernetes·devops
Su-RE9 小时前
springboo打包--微服务打包
微服务·架构·pycharm
拾忆,想起10 小时前
Dubbo vs Spring Cloud Gateway:本质剖析与全面对比指南
微服务·性能优化·架构·dubbo·safari
码界奇点10 小时前
基于Spring Cloud Alibaba与Vue.js的分布式在线教育系统设计与实现
前端·vue.js·分布式·spring cloud·架构·毕业设计·源代码管理
yumgpkpm10 小时前
hadoop集群搭建 (超详细) 接入Impala、Hive,AI 大模型的数据底座
hive·hadoop·mysql·zookeeper·flink·kafka·hbase