Spring Cloud搭建Eureka服务注册中心高可用集群

一、Eureka服务注册中心简介

Eureka 是 Netflix 的一个子模块,也是核心模块之一,它是一个基于 Rest 的服务,用于定位服务,服务注册和发现,以实现云端中间层服务发现和故障转移。

Eureka的服务注册和发现只需要使用服务的标识符,就可以访问到服务,而不需要修改服务调用的配置文件了,功能类似于 Zookeeper、Consul等服务,服务提供者【也可以是消费者】和服务消费者同时在Eureka-Server注册服务信息,当服务消费者需要远程调用服务提供者的服务时,可以直接通过在Eureka-Server注册是服务名完成服务调用,避免了url的依赖更新操作。

核心组件

  • Eureka Server:提供服务注册服务,EurekaServer 中的服务注册表中将会存储所有可用服务节点的信息
  • Eureka Client:是一个 Java 客户端,同时也具备一个内置的、集成轮询 (round-robin) 负载算法的负载均衡器

Eureka Client服务构成:

  • Service Provider 服务提供方将自身服务注册到 Eureka,从而使服务消费方能够找到
  • Service Consumer 服务消费方从 Eureka 获取注册服务列表,从而能够消费服务

图示:

springcloud zuul 多个实例 集群 springcloud搭建服务集群_java

二、集群部署原理
集群部署原理
  • 图示:
  • 原理
  • Eureka Client内置一个 使用轮询负载算法的负载均衡器。服务启动后,Eureka Client将会向Eureka Server发送心跳更新服务,如果Eureka Server在多个心跳周期内没有接收到某个服务的心跳,Eureka Server将会从服务注册表中把这个服务节点移除(默认90秒)。
  • Eureka Server是基于netflix设计出来的,其服务注册表中将会存储所有可用服务节点的信息,支持region和availabilityZone的概念,采用peer to peer的架构模式,也可以通过配置remoteRegionUrlsWithName来支持拉取远程的region实例,如果当前的region挂了,会自动fallback到远程的region获取数据,同时服务端采用renew租约和定时心跳的方式保护注册信息(self preservation机制)。
三、集群部署demo实现案例
  • 1.新建两个eureka-server服务,命名为:eureka-server-node01、eureka-server-node02
  • 更新配置文件(application.yml)
  • eureka-server-node01
#自定义微服务名称
spring:
  application:
    name: eureka-server-node01
  cloud:
    inetutils:
      ignored-interfaces:
        - VMware.*  # 忽略虚拟机网卡
      use-only-site-local-interfaces: true
      preferred-networks: 192.168.0.* # 优先使用 192.168.0.*


server:
  port: 8001

cluster:
  port01: ${server.port}
  port02: 8002

management:
  endpoints:
    web:
      exposure:
        include: "*" # 暴露所有端点

eureka:
  hostname: eureka-server-node02
  instance:
    prefer-ip-address: true
  #暴露eureka服务的地址
  client:
    serviceUrl:
      defaultZone: http://${eureka.hostname}:${cluster.port02}/eureka/
    #是否注册到eureka
    registerWithEureka: false
    #是否从eureka中拉取注册信息
    fetchRegistry: false
    # 关闭自我保护
  server:
    enable-self-preservation: true
    #清除无效节点,时间间隔为10秒
    eviction-interval-timer-in-ms: 1000
  • eureka-server-node02
#自定义微服务名称
spring:
  application:
    name: eureka-server-node02
  cloud:
    inetutils:
      ignored-interfaces:
        - VMware.*  # 忽略虚拟机网卡
      use-only-site-local-interfaces: true
      preferred-networks: 192.168.0.* # 优先使用 192.168.0.*


server:
  port: 8002

cluster:
  port01: ${server.port}
  port02: 8001

management:
  endpoints:
    web:
      exposure:
        include: "*" # 暴露所有端点

eureka:
  hostname: eureka-server-node01
  instance:
    prefer-ip-address: true
  #暴露eureka服务的地址
  client:
    serviceUrl:
      defaultZone: http://${eureka.hostname}:${cluster.port02}/eureka/
    #是否注册到eureka
    registerWithEureka: false
    #是否从eureka中拉取注册信息
    fetchRegistry: false
    # 关闭自我保护
  server:
    enable-self-preservation: true
    #清除无效节点,时间间隔为10秒
    eviction-interval-timer-in-ms: 1000
  • 更新hosts
127.0.0.1 eureka-server-node01
127.0.0.1 eureka-server-node02
  • 更新eureka-client配置例如manager-server、consumer-service
  • manager-server
#自定义微服务名称
spring:
  application:
    name: manager-server
  #端口
server:
  port: 8090

management:
  endpoints:
    web:
      exposure:
        include: "*" # 暴露所有端点

#根据刚才定义的注册中心的对外暴露的地址填写。
eureka:
  client:
    serviceUrl:
      defaultZone: http://eureka-server-node01:8001/eureka/,http://eureka-server-node02:8002/eureka/
    #每隔3秒拉取最新的注册列表(默认30秒)
    registry-fetch-interval-seconds: 3
  #心跳间隔时间为3秒(默认30秒)
  instance:
    lease-renewal-interval-in-seconds: 3
    #6秒没有接收到心跳则剔除微服务(默认90秒)
    lease-expiration-duration-in-seconds:
  • consumer-service
#自定义微服务名称
spring:
  application:
    name: consumer-service
#端口
server:
  port: 8082
  #根据刚才定义的注册中心的对外暴露的地址填写。
eureka:
  client:
    serviceUrl:
      defaultZone: http://eureka-server-node01:8001/eureka/,http://eureka-server-node02:8002/eureka/
      fetch-registry: true
      #每隔3秒拉取最新的注册列表(默认30秒)
      registry-fetch-interval-seconds: 3
  #心跳间隔时间为3秒(默认30秒)
  instance:
    lease-renewal-interval-in-seconds: 3
    #6秒没有接收到心跳则剔除微服务(默认90秒)
    lease-expiration-duration-in-seconds: 6

ribbon:
  eureka:
    enabled: true
  • 启动eureka-client服务轮询注册到,例如manager-server、consumer-service
四、测试效果
  • 访问eureka-server-node01
  • 访问eureka-server-node02
  • 停止eureka-server-node01访问eureka-server-node02【反过来一样】

springcloud zuul 多个实例 集群 springcloud搭建服务集群_java_02

五、修复集群识别为unavailable-replicas
原因解释

由于本案例是基于本地搭建,使用的自定义域名eureka-server-node01、eureka-server-node02,因此不能开启使用主机名来定义注册中心的地址,否则会导致集群节点之间识别为unavailable-replicas

  • 配置说明,其中一份为例
#自定义微服务名称
spring:
  application:
    name: eureka-server
  cloud:
    inetutils:
      # 忽略虚拟机网卡,防止使用了虚拟机网卡出现远程调用失败等问题
      ignored-interfaces:
        # 支持名称,关键字正则
        - VMware.*  
      use-only-site-local-interfaces: true
      # 优先使用 192.168.0.*
      preferred-networks: 192.168.0.* 

# 服务配置
server:
  port: 8001

# 集群部署使用配置,便于扩充管理
cluster:
  cluster1:
    hostname: eureka-server-node02
    port: 8002

management:
  endpoints:
    web:
      exposure:
        include: "*" # 暴露所有端点

eureka:
  # 使用cluster配置,因此这里不使用hostname
  # hostname: eureka-server-node02
  instance:
    # 使用主机名来定义注册中心的地址,同主机下的集群不能为true,否则集群其他服务为检测为不可用
    preferIpAddress: false
    # 当前节点的服务实例名称
    hostname: eureka-server-node01
  #暴露eureka服务的地址
  client:
    serviceUrl:
      defaultZone: http://${cluster.cluster1.hostname}:${cluster.cluster1.port}/eureka/
    #是否注册到eureka
    registerWithEureka: true
    #是否从eureka中拉取注册信息,同步集群注册信息
    fetchRegistry: true
  server:
    # 关闭自我保护
    enable-self-preservation: true
    #清除无效节点,时间间隔为10秒
    eviction-interval-timer-in-ms: 1000
解决方案,在各eureka-server服务节点更新配置
eureka:
  hostname: eureka-server-node02
  instance:
    # 使用主机名来定义注册中心的地址,同主机下的集群不能为true,否则集群其他服务为检测为不可用
    preferIpAddress: false
    # 当前节点的服务实例名称
    hostname: eureka-server-node01