spring cloud eureka 服务治理

     Spring Cloud Eureka 是 Spring Cloud Netflix 微服务套件中的一部分,它基于 Netflix Eureka 做了二次封装,主要负责完成微服务架构中的服务治理功能。主要包括:

  • Eureka 服务端
    1)服务注册中心
  • Eureka 客户端
    1)服务提供者
    2)服务消费者

本文主要内容包括:

  1. 服务治理机制

    1)服务提供者

     - 服务的注册
     - 服务的同步
     - 服务的续约
    

    2)服务消费者

     - 服务的获取
     - 服务的调用
     - 服务的下线
    

    3)服务注册中心

     - 失效剔除
     - 自我保护
    
  2. 配置详解
    1)Eureka Server 的配置

    2)Eureka Client 的配置

     - 服务注册类配置(均以 eureka.client 为前缀)
         - 指定注册中心
         - 其他配置
     - 服务实例类配置(均以 eureka.instance 为前缀)
         - 元数据
         - 实例名
         - 端点
         - 健康检测
         - 其他配置
    

服务治理机制

  服务提供者
  •   服务注册
        “服务提供者”在启动的时候会通过 Rest 请求的方式将自己注册到 Eureka Server 上,同时带上自身服务的一些元源数据。注册中心接收到请求后,将元数据信息存储在一个双层结构的 Map 中,第一层的 key 是服务名,第二层的 key 是具体服务的实例名。

服务注册在单机的服务注册中心配置:

spring.application.name=hello-service
eureka.client.serviceUrl.defaultZone=http://peer1:1111/eureka/

服务注册在集群的服务注册中心配置:

spring.application.name=hello-service   eureka.client.serviceUrl.defaultZone=http://peer1:1111/eureka/,http://peer2:1112/eureka/

    在注册服务时,要确保参数:eureka.client.register-with-eureka=true,是否正确,如果设置为false,则不会启动注册操作。

  •   服务同步

    如果服务注册中心是集群的话,当服务提供者通过 http 协议发送 rest 请求到其中的一个服务注册中心时,它会将该请求转发给集群中相连的其他注册中心,从而实现注册中心之间的服务同步。

  •   服务续约

    在注册完服务之后,服务提供者会维护一个心跳,用来通知注册中心“我还活着”,以防被注册中心的“剔除任务”将服务实例从服务列表中排除出去,这个行为称之为服务续约。

关于续约的两个属性:

# 定义服务续约任务的调用间隔时间
eureka.instance.lease-renewal-interval-in-seconds=30
# 定义服务失效的时间
eureka.instance.lease-expiration-duration-in-seconds=90
  服务消费者

    Ribbon 是基于 HTTP 和 TCP 的客户端负责均衡器,它是通过在客户端中配置的 ribbonServerList 服务端列表去轮询访问服务实例,以达到负载均衡的作用。当 Ribbon 和 Eureka 联合使用时,Ribbon 的服务实例清单 RibbonServerList 会被 DiscoveryEnabledNIWSServerList 重写,扩展成从 Eureka 注册中心中获取服务端列表,同时它也会用 NIWSDiscoveryPing 取代 IPing 。

  •   获取服务

    当启动消费者时,它会发送一个rest请求给服务注册中心,注册中心返回给客户端一份只读的服务清单,同时消费者会每隔30秒重新请求一份清单。

# 确保该参数为true,开启请求服务清单列表
eureka.client.fetch-registry=true
# 缓存清单的更新时间,默认为30s
eureka.client.registry-fetch-interval-seconds=30
  •   服务调用

    消费者获取服务清单后,通过服务名可以获得具体提供服务的实例名和实例的元数据。通过这些信息,客户端会根据自己的需要决定调用哪个实例。在 Ribbon 中默认采用轮询的方式调用,从而实现客户端的负载均衡。

  •   服务下线

    当服务实例进行正常的关闭操作时,它会触发一个服务下线的 rest 请求给注册中心,注册中心接收到请求后,将服务状态置为下线(DOWN),并把下线事件传播到其他注册中心。

  服务注册中心
  •   失效剔除

    有时候,服务实例并不一定会正常下线(内存溢出、网络故障等),这样也就没有 rest 请求发送给注册中心,那么注册中心就检测不到服务是否存活。但是,注册中心在启动的时候会创建一个定时任务,默认每隔一段时间(60s)将当前清单中超时(90s)没有续约的服务剔除出去。

  •   自我保护

    我们在本地调试基于 eureka 的程序时,基本上都会在服务注册中心的信息面板上看到一个红色的警告信息,这个警告实际上是触发了 eureka server 的自我保护机制。
    服务注册到 eureka server 之后,会维护一个心跳连接,在 eureka server 运行期间,会统计心跳失败的比例在15分钟之内是否低于85%,如果出现,eureka server 会将当前的实例信息保护起来,不让这些实例过期,尽管在这段保护期间内,实例可能会出现问题,eureka server 仍然会保护,这样,客户端很容易拿到已经挂掉的实例,导致调用失败的情况,因此客户端必须要有容错机制,比如请求重试、断路器等机制。

禁止注册中心的保护机制:

# 关闭保护机制,确保 eureka server 可以将不可用的实例正确剔除
eureka.server.enable-self-preservation=false

不可用服务实例被剔除的时间间隔:

# 过期服务剔除的默认时间为1分钟
eureka.server.eviction-interval-timer-in-ms=60000

配置详解

    Eureka Server 服务端参数均以 eureka.server 作为前缀,大多数情况下,除了自我保护机制外,不需要修改其他配置。它的所有配置参数均可在 org.springframework.cloud.netflix.eureka.server.EurekaServerConfigBean 中找到。
    Eureka Client 客户端的主要配置分为:
        1)服务注册相关:服务注册中心地址、服务列表获取的间隔时间、可用区域等
        2)服务实例相关:服务实例的名称、ip地址、端口号、健康检查路径等

  服务注册类配置(均以 eureka.client 为前缀)
  •   指定注册中心
# 此参数的配置值存储在 HashMap 中,并有一组默认值
# 默认 key:defaultZone,默认 value:http://localhost:8761/eureka/
# 单机配置
eureka.client.serviceUrl.defaultZone=http://localhost:1111/eureka/
# 集群配置
eureka.client.serviceUrl.defaultZone=http://peer1:1111/eureka/,http://peer2:1112/eureka/
# 附带安全校验
eureka.client.serviceUrl.defaultZone=http://<username>:<password>@localhost:1111/eureka/
  •   其他配置

    下面是整理了 org.springframework.cloud.netflix.eureka.EurekaClientConfigBean 中定义的常用配置参数以及对应的说明和默认值,这些参数均以 eureka.client 为前缀。

参数名说明默认值
enabled启用 Eureka 客户端true
registryFetchIntervalSeconds从 Eureka 服务端获取注册信息的间隔时间,单位为秒30
instanceInfoReplicationIntervalSeconds更新实例信息的变化到 Eureka Server 的间隔时间,单位为秒30
initialInstanceInfoReplicationIntervalSeconds初始化实例信息到 Eureka Server 的间隔时间,单位为秒40
eurekaServiceUrlPollIntervalSeconds轮询 Eureka Server 地址更改的时间间隔,单位为秒 。当与 Spring Cloud Config 配合,动态刷新 Eureka 的 serviceURL 地址时需要关注该参数300
eurekaServerReadTimeoutSeconds读取 Eureka Server 信息的超时时间,单位为秒8
eurekaServerConnectTimeoutSeconds连接 Eureka Server 的超时时间,单位为秒5
eurekaServerTotalConnections从 Eureka Client 到所有 Eureka Server 的连接总数200
eurekaServerTotalConnectionsPerHost从 Eureka Client 到每个 Eureka Server 主机的连接总数50
eurekaConnectionIdleTimeoutSecondsEureka Server 连接的空闲关闭时间,单位为秒30
heartbeatExecutorThreadPoolSize心跳连接池的初始化线程数2
heartbeatExecutorExponentialBackOffBound心跳超时重试延迟时间的最大乘数值10
cacheRefreshExecutorThreadPoolSize缓存刷新线程池的初始化线程数2
cacheRefreshExecutorExponentialBackOffBound缓存刷新重试延迟时间的最大乘数值10
useDnsForFetchingServiceUrls使用 DNS 来获取 Eureka Server 的serviceUrlfalse
registerWithEureka是否要将自身的实例信息注册到 Eureka Servertrue
preferSameZoneEureka是否偏好使用处于相同 Zone 的 Eureka Servertrue
filterOnlyUpInstances获取实例时是否过滤,仅保留 UP 状态的实例true
fetchRegistry是否从 Eureka Server 获取注册信息true
  服务实例类配置(均以 eureka.instance 为前缀)
  •   元数据

  在使用spring cloud eureka的时候,所有的配置信息都通过 org.springframework.cloud.netflix.eureka.EurekaInstanceConfigBean 进行加载,服务注册的时候,会被包装成 com.netflix.appinfo.InstanceInfo 对象发送给 Eureka 服务端。
    我们可以通过 eureka.instance.properties=value 的格式对标准化元数据直接配置,properties 就是 EurekaInstanceConfigBean 对象中的成员变量名。
    也可以自定义元数据,通过 eureka.instance.metadataMap.key=value 的格式进行配置,比如:eureka.instance.metadataMap.zone=henan,metadataMap 是 InstanceInfo 中的 ConcurrentHashMap 。

  •   实例名

    实例名,即InstanceInfo中的instanceId参数,它是区分同一服务中不同实例的唯一标识。针对同一主机启动多个相同的服务实例的情况,Spring cloud Eureka对实例名的默认命名有如下默认规则:

${spring.cloud.client.hostname}:${spring.application.name}:${spring.application.instance_id:${server.port}}

    对于实例名的命名规则,可以通过 eureka.instance.instanceId 参数配置。当我们需要启动同一服务的多个实例时,如果直接启动同一个应用必然会产生端口冲突,虽然可以指定不同的 server.port 来启动,但这样太麻烦。实际上可以通过 server.port=0 或者用随机数 server.port=${random.int[10000,19999]} 来让 tomcat 启动的时候采用随机端口,但这样注册的实例名都是相同的,这会使得只有一个服务实例能够正常提供服务。对于这个问题,可以通过设置实例名规则来解决:

# 不指定端口,直接启动同一个服务的多个实例
eureka.instance.instanceId=${spring.application.name}:${random.int}
  •   端点

    在InstanceInfo中,可以看到一些 URL 的配置信息,比如 homePageUrl(主页)、statusPageUrl(状态页)、healthCheckUrl(健康检查页)。其中,状态页和健康检查的 URL 默认使用了 spring-boot-actuator 模块提供的 /info 端点和 /health 端点。我们必须确保 eureka 的客户端的 /health 是一个能够被注册中心访问到的地址,否则注册中心不会根据应用的健康检查来更改状态(仅当开启了 healthcheck 功能时,以该端点信息作为健康检查标准)。而 /info 端点不正确的话,会导致在 eureka 面板中点击服务实例时,无法访问到服务实例提供的信息接口。
    大多数情况下,不需要修改这几个 URL 的配置,但是在一些情况下,比如,为应用设置了 context-path,这是所有的 spring-boot-actuator 模块的监控端点都会增加一个前缀,因此 /info 和 /health 端点也要加上类似的前缀信息:

相对路径配置方式:

management.context-path=/hello
eureka.instance.statusPageUrlPath=${management.context-path}/info
eureka.instance.healthCheckUrlPath=${management.context-path}/health
# 为了安全考虑,也可能修改 /info 和 /health 端点的原始路径:
endpoints.info.path=/appinfo
endpoints.health.path=/checkHealth
eureka.instance.statusPageUrlPath=/${endpoints.info.path}
eureka.instance.healthCheckUrlPath=/${endpoints.health.path}

绝对路径配置方式:

# 上面使用的 statusPageUrlPath 和 healthCheckUrlPath 都使用相对路径进行配置,由于注册中心默认会以 HTTP 的方式来访问和暴露这些端点,因此当客户端应用以HTTPS的方式时,相对路径的配置方式就不满足需求了。
eureka.instance.statusPageUrl=https://${eureka.instance.hostname}/info
eureka.instance.healthCheckUrl=https://${eureka.instance.hostname}/health
eureka.instance.homePageUrl=https://${eureka.instance.hostname}/
  •   健康检测

    默认情况下,Eureka 中各个服务实例的健康检测并不是通过 spring-boot-actuator 模块的 /health 端点实现的,而是依靠客户端心跳的方式来保持服务实例的存活。但是,由于大多数微服务应用都会有一些其他的外部资源依赖,比如数据库、缓存、消息代理等,如果我们的应用无法与这些资源联调,实际上已经不能正常的对外服务了,但是心跳检测依然在运行,所以还是会被服务消费者调用。在 spring cloud eureka 中,可以通过简单的配置,把 eureka 客户端的健康检查交给 spring-boot-actuator 模块的 /health 端点,以实现更加全面的健康状态维护。
1)在 pom.xml 中引入 spring-boot-starter-actuator 模块
2)在 application.properties 中增加参数配置 eureka.client.healthcheck.enabled=true
3)如果客户端路径做了特殊处理,参考端点配置时的方法进行配置

  •   其他配置

    除了上面介绍的配置参数外,下面整理了一些 org.springframework.cloud.netflix.eureka.EurekaInstanceConfigBean 中定义的配置参数以及对应的说明和默认值,这些参数均以 eureka.instance 为前缀。

参数名说明默认值
preferIpAddress是否优先使用 IP 地址作为主机名的标识false
leaseRenewalIntervalInSecondsEureka Client 向 Eureka Server 发送心跳的时间间隔,单位为秒30
leaseExpirationDurationInSecondsEureka Server 在收到最后一次心跳之后等待的时间上线,单位为秒。超过该时间之后,Eureka Server 会将该服务实例从服务清单中剔除90
nonSecurePort非安全的通信端口号80
securePort安全的通信端口号443
nonSecurePortEnabled是否启用非安全的通信端口号true
securePortEnabled是否启用安全的通信端口号
appname服务名,默认取 spring.application.name 的配置值,如果没有则为 unknown
hostname主机名,不配置的时候将根据操作系统的主机名来获取

以上这些配置中,除了前三个配置参数在需要的时候可以做一些调整,其他的参数配置大多数情况下使用默认值即可。

Eureka 的跨平台支持

    Eureka 的通信机制使用了 HTTP 的 REST 接口实现,由于 HTTP 的平台无关性,虽然 Eureka Server 通过 Java 实现,但是在其下的微服务应用并不限于使用 Java 来进行开发。
    默认情况下,Eureka 使用 jersey 和 XStream 配合 JSON 作为 Server 与 Client 之间的通信协议,当然也可以实现自己的协议来代替。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值