解决什么问题
➟阐述微服务以及服务注册发现的部分概念
➟阐述Eureka服务注册与发现的部分原理及细节
为什么需要服务中心
过去,每个应用都是一个CPU,一个主机上的单一系统。然而今天,随着大数据和云计算时代的到来,任何独立的程序都可以运行在多个计算机上。并且随着业务的发展,访问用户量的增加,开发人员或小组的增加,系统会被拆分成多个功能模块。拆分后每个功能模块可以作为一个独立的子系统提供其职责范围内的功能。而多个子系统中,由于职责不同并且会存在相互调用,同时可能每个子系统还需要多个实例部署在多台服务器或者镜像中,导致了子系统间的相互调用形成了一个错综复杂的网状结构。用几幅图说明一下:
单体应用:
随着业务的发展,经过了多个系统架构的演变,变成了这样(拿百度的功能举个栗子):
图中,每个网页搜索子系统和百度地图子系统的实例都可以视同为一个微服务。网页搜索子系统为百度地图子系统提供了“用户查询内容、用户IP地址”等信息提供的服务接口,为百度地图子系统定位用户地理信息情况提供数据依据。
百度地图子系统提供了“根据内容查询出地图信息”的接口提供给其他子系统调用,而这里网页搜索子系统调用了这个接口,获取地图相关信息。
网页搜索子系统和百度地图子系统又提供了各自对外用户调用的网页搜索、地图搜索等各自的对外服务。这个过程就形成了以上错综复杂的网状结构。而实际上这样还远远不够,因为每个子系统往往会提供多个对内的其他子系统调用的服务接口,同时也会调用多个不同子系统提供的多个服务接口,还会对外提供多个各自的服务接口。所以实际中上图的网状调用结构将会成几何倍的扩张。而且随着用户量的增加,每个子系统还需要继续增加更多的实例来提供服务,从而导致了凌乱的加剧。
对于微服务之间错综复杂的调用关系,通过eureka来管理,可以让每个服务之间不用关心如何调用的问题,专注于自己的业务功能实现。
从系统架构的演变到对于微服务架构的思考
为什么上图中的系统演变最终会变成如图所示的样子?这是一种架构思维,这里不扩展来说。简单描述一下微服务架构是为了解决什么问题。随着系统结构、架构的演变,系统功能的增加,用户量的增加,开发人员的增加等各种增加情况下,需要有一个比较好扩展的系统架构来快速、尽量减少代码改动的前提下以支持系统功能的开发,用户量增加导致的硬件资源横向扩容,以及开发人员增加时的协同工作效率。在此基础上需要解决系统的稳定性、容错性、高并发的支持性等。以及随着系统功能的增加如何有效的管理系统,排查、定位系统问题。同时当参与项目的人(包含测试、运维、业务等人员)越来越多时,如何能更高效的彼此之间协同办公的效率等等。
所以微服务架构需要考虑的不仅仅是软件架构本身,需要从参与到整个项目实施过程中的各个环节,可能的问题以及人员协同的整体情况去考虑。让整个项目做到可用(满足功能以及硬件资源的横向扩容)、可行(满足整个系统运行中的各个点的监控、排错等)、可持续(满足系统功能的可持续集成、以及系统运行的可持续性)以及高效(系统运行的高效、人员协同工作的高效、功能迭代的高效等)。
Eureka应用场景中的一些概念
微服务:
Spring Cloud提供了微服务解决的一整套方案,而Eureka是其重要组件,所以先要了解什么是“微服务”。在大型系统架构中,会拆分多个子系统。这些系统往往都有这几个功能:提供接口,调用接口,以及该子系统自身的业务功能。这样的一个子系统就称为一个“微服务”。(可以理解为一个子系统的代码所实现的功能)
比如百度的搜索子系统,就具备了:根据用户的输入的信息对信息分词功能、对每个分词给予权重功能、然后根据分词和权重等信息计算出网页相关度功能、最后把相关度高的网页按照一定算法排序后提供结果功能、记录用户录入信息功能等等业务功能。同时它还提供用户录入信息提供的接口给其它子系统调用,如地图子系统、广告推荐子系统会调用该接口后完成各自的业务功能。同时搜索子系统也会调用其它子系统的接口,如调用地图子系统的地图显示接口等。
实例:
每个服务都会部署到多个机器(或镜像)中,这些多个部署的应用就是实例。(可以理解为一套子系统代码被部署到了多个机器上)
Eureka的管理:
基于以上概念,使用Eureka管理时会具备几个特性:
→服务需要有一个统一的名称(或服务ID)并且是唯一标识,以便于接口调用时各个接口的区分。并且需要将其注册到Eureka Server中,其他服务调用该接口时,也是根据这个唯一标识来获取。
→服务下有多个实例,每个实例也有一个自己的唯一实例ID。因为它们各自有自己的基础信息如:不同的IP。所以它们的信息也需要注册到Eureka Server中,其他服务调用它们的服务接口时,可以查看到多个该服务的实例信息,根据负载策略提供某个实例的调用信息后,调用者根据信息直接调用该实例。
eureka如何管理服务调用
eureka如何管理服务调用的?我们先来看个图:
→在Eureka Client启动的时候,将自身的服务的信息发送到Eureka Server。然后进行2调用当前服务器节点中的其他服务信息,保存到Eureka Client中。当服务间相互调用其它服务时,在Eureka Client中获取服务信息(如服务地址,端口等)后,进行第3步,根据信息直接调用服务。(注:服务的调用通过http(s)调用)
→当某个服务仅需要调用其他服务,自身不提供服务调用时。在Eureka Client启动后会拉取Eureka Server的其他服务信息,需要调用时,在Eureka Client的本地缓存中获取信息,调用服务。
→Eureka Client通过向Eureka Serve发送心跳(默认每30秒)来续约服务的。 如果客户端持续不能续约,那么,它将在大约90秒内从服务器注册表中删除。 注册信息和续订被复制到集群中的Eureka Serve所有节点。 以此来确保当前服务还“活着”,可以被调用。
→来自任何区域的Eureka Client都可以查找注册表信息(每30秒发生一次),以此来确保调用到的服务是“活的”。并且当某个服务被更新或者新加进来,也可以调用到新的服务。
简单的了解了eureka如何管理服务调用的之后,我们看看官网提供的图片,进一步了解更多信息(官网地址:https://github.com/Netflix/eureka/wiki/Eureka-at-a-glance):
这个图从上而下,首先看到us-east-1c、us-east-1d、us-east-1e这些代表了一个可用区。简单举个栗子,假设一个Eureka Server集群下面的分布情况是这样的:
“北京集群中心”是一个区域,北京市内的机房A和B为可用区(对应官网图片中的us-east-1c、us-east-1d、us-east-1e)。区域(Region)和可用区(Zone或者Availability Zone)均是AWS的概念。在非AWS环境下,我们可以简单地将region理解为Eureka某个地区的集群中心,zone理解成该区域的每个机房。每个区域是通过外网连接,所以速度、稳定性上不能保证。而每个可用区之间一般是内网直连,保证速度。想更多了解AWS概念的可用查看http://blog.csdn.net/awschina/article/details/17639191
回到官网的图片可以看出在这个体系中,有2个主体:Eureka Server和Eureka Client。
Eureka Server:
提供服务注册:各个微服务启动时,会通过Eureka Client向Eureka Server进行注册自己的信息(例如服务信息和网络信息),Eureka Server会存储该服务的信息。
提供服务信息提供:服务消费者在调用服务时,本地Eureka Client没有的情况下,会到Eureka Server拉取信息。
提供服务管理:通过Eureka Client的Cancel、心跳监控、renew等方式来维护该服务提供的信息以确保该服务可用以及服务的更新。
信息同步:每个Eureka Server同时也是Eureka Client,多个Eureka Server之间通过P2P复制的方式完成服务注册表的同步。同步时,被同步信息不会同步出去。也就是说有3个Eureka Server,Server1有新的服务信息时,同步到Server2后,Server2和Server3同步时,Server2不会把从Server1那里同步到的信息同步给Server3,只能由Server1自己同步给Server3。
每个可用区有一个Eureka集群,并且每个可用区至少有一个eureka服务器来处理区内故障。为了实现高可用,一般一个可用区中由三个Eureka Server组成。
Eureka Client
Eureka Client是一个Java客户端,用于简化与Eureka Server的交互。并且管理当前微服务,同时为当前的微服务提供服务提供者信息。
Eureka Client会拉取、更新和缓存Eureka Server中的信息。即使所有的Eureka Server节点都宕掉,服务消费者依然可以使用缓存中的信息找到服务提供者。
Eureka Client在微服务启动后,会周期性地向Eureka Server发送心跳(默认周期为30秒)以续约自己的信息。如果Eureka Server在一定时间内没有接收到某个微服务节点的心跳,Eureka Server将会注销该微服务节点(默认90秒)。
Eureka Client包含服务提供者Applicaton Service和服务消费者Application Client
Applicaton Service:服务提供者,提供服务给别个调用。
Application Client:服务消费者,调用别个提供的服务。
往往大多数服务本身既是服务提供者,也是服务消费者。
其它动作:
Register:服务注册
当Eureka客户端向Eureka Server注册时,它提供自身的元数据,比如IP地址、端口,运行状况指示符URL,主页等。
Renew:服务续约
Eureka Client会每隔30秒发送一次心跳来续约。 通过续约来告知Eureka Server该Eureka客户仍然存在,没有出现问题。 正常情况下,如果Eureka Server在90秒没有收到Eureka客户的续约,它会将实例从其注册表中删除。 建议不要更改续约间隔。
Fetch Registries:获取注册列表信息
Eureka客户端从服务器获取注册表信息,并将其缓存在本地。客户端会使用该信息查找其他服务,从而进行远程调用。该注册列表信息定期(每30秒钟)更新一次。每次返回注册列表信息可能与Eureka客户端的缓存信息不同, Eureka客户端自动处理。如果由于某种原因导致注册列表信息不能及时匹配,Eureka客户端则会重新获取整个注册表信息。 Eureka服务器缓存注册列表信息,整个注册表以及每个应用程序的信息进行了压缩,压缩内容和没有压缩的内容完全相同。Eureka客户端和Eureka 服务器可以使用JSON / XML格式进行通讯。在默认的情况下Eureka客户端使用压缩JSON格式来获取注册列表的信息。
Cancel:服务下线
Eureka客户端在程序关闭时向Eureka服务器发送取消请求。 发送请求后,该客户端实例信息将从服务器的实例注册表中删除。该下线请求不会自动完成,它需要调用以下内容:
DiscoveryManager.getInstance().shutdownComponent();
Eviction 服务剔除
在默认的情况下,当Eureka客户端连续90秒没有向Eureka服务器发送服务续约,即心跳,Eureka服务器会将该服务实例从服务注册列表删除,即服务剔除。
结语:了解了以上一些基础的概念和原理,对于Eureka的运行情况以及Eureka配置的理解就相对容易多了。最后附上一个转载来的Eureka参数配置项详解:https://juejin.im/post/5a37726051882574d23c70a9
所有评论(0)