作为一个服务注册以及发现中心,主要解决一下几个问题
服务实例如何注册到服务中心
服务启动时候,调用Eureka Server的REST API 的register方法去注册该应用实例的信息。对于java应用通过Netflix的Eureka Client封装API去调用;对于SpringCloud应用通过spring-cloud-starter-netflix-eureka-server然后基于springboot自动配置自动实现服务信息的注册
服务实例如何从服务中心剔除
正常请款改下服务实例在关闭应用的时候,通过钩子方法或者其他生命周期回调方法去调用API的do-register方法来删除自身服务的实例信息。另外解决服务实例挂掉或者异常情况时没有及时删除自身信息得问题。Eureka server要求Client端进行续约,也就是发送心跳来证明反腐无实例是否存活是健康的并且可以调用的。如果租约超过一定时间没有进行续约操作,Eureka server端就会主动提出。这一点Eureka server采用的就是分布式应用里经典的心跳模式。
服务实例信息的一致性问题
服务注册一级发现中心不可能是单点的,name服务实例注册信息如何在集群环境下保持执行呢?下面主要分AP优于CP、Peer to Peer架构、Zone及Region设计、SELF PRESERVATION设计四个方面来阐述。
AP优于CP
分布式系统CAP三个特行:consistency一致性、Availability可用性、Partition Tolerance分区容忍性
对于分布式系统来说,一般网络环境相对不可控,出现网络分区是不可避免的,因此系统必须具备分区容忍性。在这个前提下分布式系统设计则在AP以及CP之间进行选择,不过不能理解CAP三者之间必须三选二。
ZooKeeper他是"C"P,他默认并不是严格的强一致性。
Eureka实在不是在AWS的背景下设计的,其设计者认为在云端特别是在大规模部署的情况下,失败是不可能避免的,可能是因为Eureka本身部署失败注册的服务不可用,或者又去网络分区导致服务不可用,因此不能回避这个问题,则需要Eureka在网络分区的时候,还能够正常提供服务注册一级发现功能,因此Eureka选择满足Availability这个特性。有文中指出,在实际生产实践中,服务注册以及发现中心保留可用以及火气的数据总比丢失掉可用的数据好。这样的话应用实例注册信息在集群所有节点并不是强一致性的,这就需要客户端能够支持负载均衡以及失败重试。在Netflix的生态中有ribbon提供这个功能。
Peer to Peer架构
分布式系统数据在多个副本之间的复制方式可分为主从复制以及对等复制
主从复制:Master-Slavem模式,主服务同步更新到其他副本。更新方式可以细分为同步更新、异步更新、同步以及异步混合。对于主从复制模式来讲,写操作的压力都在祝福本上,他是整个系统的瓶颈,但是从副本可以帮主副本分担读请求。
对等复制:即Peer to Peer复制模式,副本之间部分主从,任何副本都可以接口写操作然后每个副本之间相互进行数据更新。由于任何副本都可以接口写操作,不存在写操作压力瓶颈,但各个副本之间的数据同步以及冲突处理是比较棘手的问题。
数据同步:单个Eureka server启动时,执行syncUp操作然后复制到其他peer节点,在执行复制操作的时候,通过http head中加入HEADER_REPLICATION标识为复制请求,避免其他peer节点接收到请求无厘头进行复制操作导致死循环。
冲突处理:Eureka采用lastDirtyTimestamp标识【类似版本号机制】和heartbeat【renewLease兜底操作-重新进行register操作】来解决
Zone及Region设计
Eureka Server原生支持了Region以及AZ,由于资源在Region之间默认是不会复制的,因此Eureka Server的高可用主要就在于Region下面的AZ。
Eureka Client支持preferSameZone,也就是获取服务的serviceUrl有限拉去跟应用实在痛处一个AZ的服务端地址列表,一个AZ可以设置多个服务端实例,他们之间构成peer节点然后此阿勇Peer to Peer的复制模式
Netflix的Rebbon组件针对多个AZ提供了ZoneAffinity支持,允许在客户端路由或者网管路由时,有限选择与自身实例处于同一个AZ的服务实例
SELF PRESERVATION设计
客户端和服务端通过心跳来维持租约,Eureka通过当前注册实例数去计算每分钟应该从应用实例接受到的心跳数。如果浸一分钟接受的心跳书小于制定阈值的话,则关闭逐月失效剔除,禁止定时任务剔除失效的实例,从而保护注册信息。
到底什么是Partition Tolerance分区容忍性
一个分布式系统里面,节点组成的网络本来应该是连通的。然而可能因为一些故障,使得有些节点之间不连通了,整个网络就分成了几块区域。数据就散布在了这些不连通的区域中。这就叫分区。当你一个数据项只在一个节点中保存,那么分区出现后,和这个节点不连通的部分就访问不到这个数据了。这时分区就是无法容忍的。提高分区容忍性的办法就是一个数据项复制到多个节点上,那么出现分区之后,这一数据项就可能分布到各个区里。容忍性就提高了。
解决分区容错性->复制->引发C->引发A
当没有出现分区问题的时候,系统就应该有完美的数据一致性和可用性。