• springcloud实践(一)服务发现:Eureka


    Eureka 入门

    是什么?

    Eureka 是 Netflix 开源的一个 RESTful服务,主要用于服务注册与发现。

    它由Eureka server 和Eureka client组成。

    Eureka server提供服务的注册、删除、查询、续约等功能,是服务管理中心。

    Eureka cliet用来向server注册服务、查询服务、调用服务等。

    Eureka 中的3个角色

    image

    Eureka有三种角色:

    1. Service Registy服务注册表,提供注册和查询服务
    2. Provider向服务注册表注册服务、续约服务
    3. Consumer从服务注册表查询到Provider的服务实例,并且选择实例进行直接调用。

    Service Registy服务注册中心

    1. 数据如何存储。可以保持在内存、本地文件、数据库等等
    • Eureka采用保持在内存中。
    1. 如何提供注册服务。Http、Rpc等等
    • Eureka提供http方式注册服务
    1. 如何提供查询服务。
    • 服务消费者向服务注册中心查询服务提供方信息,并缓存到本地。
    1. Provider变化时,如何通知Consumer。采用推的方式还是拉的方式,实时还是定时等
    • Eureka采用实时推送
    1. 服务注册表的节点之间如何进行信息的同步和复制
    • 简单说,就是请求转发,后面会展开讲
    1. 当所有的服务注册表节点都Down掉后重新启动,如何重新获取注册信息。从数据库中重新加载,从缓存中读取,还是需要Provider发送心跳时重新保存
    • Eureka在Provider发送心跳时重新保存。

    Service Provider 服务提供方

    1. 启动时向服务注册表发送注册信息:服务注册
    2. 关闭时向服务注册表发送取消信息:服务下线
    3. 保持心跳,使得服务注册表能够获取Provider的最新情况:服务续约

    Service Consumer 服务消费者

    1. 通过服务注册表查询Provider的实例:服务获取
    2. 客户端负载均衡:Ribbon
    3. 客户端缓存:本地缓存

    入门Demo示例

    网上demo很多,仅供参考。
    史上最简单的SpringCloud教程 | 第二篇: 服务消费者(rest+ribbon)

    Eureka 进阶

    Eureka 如何管理服务?

    服务治理的本质:服务的增删改查。

    增:注册。有服务提供方向服务注册中心注册。

    删:服务清除。服务注册中心将定时清除失效服务。

    改:无

    查:服务发现、获取。由服务消费者向服务注册中心获取服务提供方信息。

    服务续约:服务提供方定时向服务注册中心发送心跳(默认30秒发送一次),服务提供方超过一段时间(默认90秒)未向服务注册中心发送心跳,则服务注册中心将服务下线。

    由于数据是缓存在本地,主要就是对registry变量进行操作。

    private final ConcurrentHashMap<String, Map<String, Lease<InstanceInfo>>> registry =new ConcurrentHashMap<String, Map<String, Lease<InstanceInfo>>>();
    

    高可用性-->集群

    如何构建集群?

    Eureka server 还可以作为 Eureka client,指向另外一个Eureka Server。

    Eureka sever A

    spring:
      profiles: development_ha1
      application:
          name: eureka-server-ha1
    eureka:
      server:
        enable-self-preservation: false  #关闭自我保护,仅在开发环境中采用此配置。
        eviction-interval-timer-in-ms: 3000
      instance:
        prefer-ip-address: true
        lease-expiration-duration-in-seconds: 10
        lease-renewal-interval-in-seconds: 3
      client:
        registry-fetch-interval-seconds: 3 # 默认为30秒
        serviceUrl:
          defaultZone: http://ziyun:dd2016@192.168.100.119:10001/eureka/
    

    Eureka sever B

    spring:
      profiles: development_ha2
      application:
          name: eureka-server-ha2
    eureka:
      server:
        enable-self-preservation: false   #关闭自我保护,仅在开发环境中采用此配置。
        eviction-interval-timer-in-ms: 3000
      instance:
        prefer-ip-address: true
        lease-expiration-duration-in-seconds: 10
        lease-renewal-interval-in-seconds: 3
      client:
        registry-fetch-interval-seconds: 3 # 默认为30秒
        serviceUrl:
          defaultZone: http://ziyun:dd2016@192.168.100.118:10001/eureka/
    

    关键配置为

    client:
        serviceUrl:
          defaultZone: http://ziyun:dd2016@192.168.100.118:10001/eureka/
          
    client:
        serviceUrl:
          defaultZone: http://ziyun:dd2016@192.168.100.119:10001/eureka/
    
    

    How Peer Replicates集群如何进行同步?

    具体实现方式:接收到Service Provider请求的Eureka Server,把请求再次转发到其它的Eureka Server,调用同样的接口,传入同样的参数,除了会在header中标记isReplication=true,从而避免重复的replicate。

    How New Peer Initializes新节点初始化

    启动时把自己当做是Service Consumer服务消费者,从其它Peer Eureka获取(get Registry)所有服务的注册信息(即相当于获取服务列表)。然后遍历服务列表,对每个服务,在自己这里执行Register,isReplication=true,从而完成初始化。

    Why not use HA proxy for load balancing?

    1. 跟session无关时,可以不用ha proxy;
    2. haproxy的弹性、灵活度没有Eureka client高, 因为Eureka server可能会动态变化。

    Resilience 弹性

    Eureka clients are built to handle the failure of one or more Eureka servers. Since Eureka clients have the registry cache information in them, they can operate reasonably well, even when all of the eureka servers go down.Eureka clients将数据缓存在本地,即使所有Eureka servers都挂了,仍能正常运行。

    Eureka Servers are resilient to other eureka peers going down. Even during a network partition between the clients and servers, the servers have built-in resiliency to prevent a large scale outage.
    当其他server挂了,或者网络中断了, server仍能独立工作

    Non-Java services and clients

    对于非java语言的服务:

    1. 用该语言实现client的功能
    2. 通过side car 机制实现。

    Why not use Curator/Zookeeper as a service registry?(本人未使用过在zookeeper,就不在此深究)

    官方说法:

    There are some overlaps in certain areas of what Zookeeper and Eureka provide especially in the areas of replicating registry information. Eureka could use zookeeper to cache registry information and replicate the same, but replication is just a small part of what Eureka provides.

    Eureka deals with various other things apart from replication:

    • REST end points that deal with registrations, renewals, expirations and cancels.
    • Keeping the instance information up-to-date dealing with the intricacies of EIP binding, deployment rollbacks, autoscaling in a resilient manner.
    • Being resilient to network outages between clients and servers and between peers.

    Zookeeper's power comes to the fore with leader election, ordered updates, distributed synchronization along with its consistency guarantees (quorums).

    None of the above except the replication registry really applies to Eureka to justify an other dependency that we have to deal with the following complications:

    • You will have to now find a way to assign EIPs to zookeeper similar to Eureka.
    • Deal with failures when zookeeper fails.

    And further more, Eureka has been built carefully without any hard dependency on any external components .

    • Most services rely on Eureka to bootstrap themselves.
    • To reduce the complexity.
    • Avoid another failure point.

    另外一篇文章中也做了对比:Zookeeper做注册中心的缺陷

    文中主要提出了三个缺点:

    • ZooKeeper无法很好的处理网络分区问题,当网络分区中的客户端节点无法到达Quorum时,会与ZooKeeper失去联系,从而也就无法使用其服务发现机制。(在ZooKeeper中,如果在同一个网络分区(partition)的节点数(nodes)数达不到 ZooKeeper选取Leader节点的“法定人数”时,它们就会从ZooKeeper中断开,当然同时也就不能提供Service发现服务了。)
    • 服务发现系统应该是一个AP系统,设计上针对可用性;而ZooKeeper是一个CP系统。
    • ZooKeeper的设置和维护非常困难,实际操作的时候也容易出错,比如在客户端重建Watcher,处理Session和异常的时候。

    当然,Peter Kelley提出的这几个问题并不是不能克服的,并不能说明基于ZooKeeper就不能做好一个服务发现系统,但是我们可能有更简洁的方案比如Eureka来实现。

    安全身份验证

    Eureka Server的安全认证官网链接-老版本
    在最新版本中放在了config中 client

    如果客户端的eureka.client.serviceUrl.defaultZone参数值(即Eureka Server的地址)中包含HTTP Basic Authentication信息,如http://user:password@localhost:8761/eureka,那么客户端就会自动使用该用户名、密码信息与Eureka服务端进行验证。如果你需要更复杂的验证逻辑,你必须注册一个DiscoveryClientOptionalArgs组件,并将ClientFilter组件注入,在这里定义的逻辑会在每次客户端向服务端发起请求时执行。

    server端配置:

    security:
      user:
         name: ziyun
         password: dd2016
         
    <dependency>
    	<groupId>org.springframework.boot</groupId>
    	<artifactId>spring-boot-starter-security</artifactId>
    </dependency>
    
    

    client配置

    http://user:password@EurekaHost:EurekaPort/eureka/
    
    eureka:
      client:
        serviceUrl:
          defaultZone: http://ziyun:dd2016@eureka-server:10001/eureka/
    

    note: 密码不能带特殊符号!!!

    常见问题及解决方案

    1. Eureka进入了自我保护模式,

    提示信息如下: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.

    解决方案:

     1、 注册中心关闭自我保护机制,修改检查失效服务的时间。
    
    eureka:
      server: 
        enable-self-preservation: false
        eviction-interval-timer-in-ms: 3000
    2、 微服务修改减短服务心跳的时间。
    
    # 默认90秒
    lease-expiration-duration-in-seconds: 10
    # 默认30秒
    lease-renewal-interval-in-seconds: 3
    
    
    eureka:
      server:
        enable-self-preservation: false  #关闭自我保护,仅在开发环境中采用此配置。
        eviction-interval-timer-in-ms: 3000 续期时间,即扫描失效服务的间隔时间(缺省为60*1000ms)
      instance:
        prefer-ip-address: true
        lease-expiration-duration-in-seconds: 10 # 发呆时间,即服务续约到期时间(缺省为90s)
        lease-renewal-interval-in-seconds: 3 # 心跳时间,即服务续约间隔时间(缺省为30s)
      client:
        registry-fetch-interval-seconds: 3 # 默认为30秒
    

    产生原因:Eureka Server在运行期间,会统计心跳失败的比例在15分钟之内是否低于85%,如果出现低于的情况(在单机调试的时候很容易满足,实际在生产环境上通常是由于网络不稳定导致),Eureka Server会将当前的实例注册信息保护起来,同时提示这个警告。保护模式主要用于一组客户端和Eureka Server之间存在网络分区场景下的保护。一旦进入保护模式,Eureka Server将会尝试保护其服务注册表中的信息,不再删除服务注册表中的数据(也就是不会注销任何微服务)。

    1. 如何处理服务挂掉后或者手动关闭服务后,Ribbon负载均衡还是一直调用这个服务,然后调用@HystrixCommand断路器注解的方法:利用Hystrix,在error callback方法中可以shutdown指定的server
    ZoneAwareLoadBalancer<Server> lb = (ZoneAwareLoadBalancer<Server>) springClientFactory.getLoadBalancer("CLOUD-SERVICE");
    Server server = lb.chooseServer();
    System.out.println("error->" + server.getHostPort());
    lb.markServerDown(server);
    

    另外在Camden.SR3中可以配置Ribbon请求重试,可以参考DD大神的新作:为Spring Cloud Ribbon配置请求重试(Camden.SR2+)

    1. 改变eureka server中注册的服务的健康检测方式

    默认的心跳实现方式可以有效的检查eureka客户端进程是否正常运作,但是无法保证客户端应用能够正常提供服务。

    由于大多数微服务应用都会有一些其他的外部资源依赖,比如数据库,REDIS缓存等,如果我们的应用与这些外部资源无法连通的时候,实际上已经不能提供正常的对外服务了,但因为客户端心跳依然在运行,所以它还是会被服务消费者调用,而这样的调用实际上并不能获得预期的后果。

    我们可以通过在eureka客户端中配置:eureka.client.healthcheck.enabled=true,就可以改变eureka server对客户端健康检测的方式,改用actuator的/health端点来检测。

    改变eureka server中注册的服务的健康检测方式

    Spring Cloud实战小贴士:健康检查

    替代性技术

    SpringCloud提供了3个服务发现组件:Eureka/Consul/Zookeeper。在摩拜公开的SpringCloud实践的PPT中,采用了是Consul。

    参考文献

  • 相关阅读:
    吴裕雄 Bootstrap 前端框架开发——Bootstrap 字体图标(Glyphicons):glyphicon glyphicon-print
    吴裕雄 Bootstrap 前端框架开发——Bootstrap 字体图标(Glyphicons):glyphicon glyphicon-bookmark
    吴裕雄 Bootstrap 前端框架开发——Bootstrap 字体图标(Glyphicons):glyphicon glyphicon-book
    ListView与RadioButton组合——自定义单选列表
    谷歌邮箱上不了的情况下怎么登录谷歌邮箱
    Valid page threshold based garbage collection for solid state drive
    Win10 owerShell Get命令大全
    程序员每天应该思考的5个问题,你有思考过吗?
    程序员每天应该思考的5个问题,你有思考过吗?
    程序员每天应该思考的5个问题,你有思考过吗?
  • 原文地址:https://www.cnblogs.com/small-k/p/8150113.html
Copyright © 2020-2023  润新知