Spring Cloud 提供了大规模部署微服务所必需的支持。为了获得像云服务环境一样的能力, 微服务实例也应该能够根据流量的规模来自动扩展,也称自动缩放( Auto-scaling)。
Spring Cloud有两个重要的概念,称为自我注册( self-registration )和自我发现( self-discovery )。
这两个功能支持自动化的微服务部署。通过自我注册,只要微服务实例做好准备,微服务就可以通过向中央服务注册中心( 服务注册表)注册服务元数据来自动发布该服务,并确保其可用。一旦微服务被注册,消费者就可以通过使用注册服务来发现新注册服务实例,接着就能消费这些服务。其中,服务注册表是这种自动化的核心。
Spring Cloud与传统的JAVA EE应用服务器采用的传统的集群方法完全不同。在Java EE应用程序服务器部署的过程中,服务器实例的IP地址或多或少地需要在负载均衡器中静态配置。因此,集群方法并不是在互联网大规模部署中进行自动扩展的最佳解决方案。此外,集群还会带来其他挑战,例如,它们必须在所有集群节点上具有完全相同的二进制文件版本。由于集群中的节点之间紧密的依赖关系,一个集群节点的故障也可能会使其他节点不可用。
在Spring Cloud中,服务注册表会将服务实例解耦。它还消除了在负载平衡器中手动维护服务地址或配置虚拟IP的烦琐过程。
在图14-1所示的Spring Cloud的服务注册和发现架构示意图中,自动化微服务部署主要由三个关键组件组成。
●服务注册表:主要由Eureka Server来实现,是微服务注册和发现的中心注册组件。服务的消费者和提供者都可以通过RESTAPI来访问注册表。注册表还包含服务元数据,如服务标识、主机、端口、健康状态等信息。
●客户端:主要由Eureka Client来实现,结合Ribbon客户端一 起提供了客户端动态负载平衡。
消费者使用Eureka Client查找Eureka Server, 从而识别出目标服务的可用实例列表。Ribbon客户端使用此服务器列表在可用的微服务实例之间进行负载平衡。同样的,如果服务实例退出服务,这些实例将被从Eureka注册表中取出。负载均衡器会自动对这些动态的更改做出反应。
●微服务实例:该组件是基于Spring Boot开发的微服务实例。
以上便是前面已经实践过的部署方案。但是,这种方案存在一个缺陷,那就是当需要额外的微服务实例时,需要执行手动任务来启动新的实例。在理想情况下,微服务实例的启动和停止最好也能够自动化,从而解放手动操作。
例如,当需要添加另--个城市数据API微服务实例来处理流量增长或负载突发情况时,运维人员不得不手动去启动一个新实例。此外,城市数据API微服务实例空闲一段时间时,运维人员需要手动停止服务以获得最佳的基础设施使用率。特别是当服务使用的是按使用付费的云环境时,这对于节约成本尤其重要。
自动扩展是一种基于资源使用情况自动扩展实例的方法,通过复制要缩放的服务来满足SLA( Service Level Agreement,服务等级协议)。
具备自动扩展能力的系统,会自动检测到流量的增加或减少。如果是流量增加,则会增加服务实例,从而能够使其可用于流量处理。同样的,当流量下降时,系统会通过从服务中取回活动实例来减少服务实例的数量。
如图14-2所示,微服务通常会使用一-组备用机器完成自动扩展。
由于云环境都是基于“即用即付”的模式,因此这是定位云部署的关键功能。这种方法通常称为弹性,也称为动态资源提供和取消。自动扩展是一-种有 效的方法,专门针对具有不同流量模式的微服务。例如,购物网站通常会在“双十一”的时候迎来服务的最高流量,服务实例当然也是最多的。如果平时也配置那么多的服务实例,显然就是浪费。Amazon就是这样一- 个很好的实例,Ama-zon总是会在某个时间段迎来流量的高峰,此时,就会配置比较多的服务实例来应对高访问量。而在平时流量比较小的情况下,Amazon 就会将闲置的主机出租出去,用来收回成本。正是拥有这种强大的自动扩展的实践能力,造就了Amazon从一个网上书店成为世界云计算巨头。
在自动扩展的方法中,通常会有- -个资源池和多个备用实例。根据需求,将实例从资源池移到活动状态以满足剩余需求。在一-些高级部署场景中,这些实例并不会针对特定的微服务来预先打包成微服务的二进制文件,而是从资源库(如Nexus)中进行下载。
实现自动扩展机制有很多好处。在传统部署中,运维人员会针对每个应用程序预留一-组服务 器。
通过自动扩展,这个预分配将不再需要。因为这些预分配的服务器,可能会导致在很长一段实间内未充分得到利用,从而演变成为一种浪费。在这种情况下,即使邻近的服务需要争取更多的资源,这些空闲的服务器也不能使用。通过数百个微服务实例,为每个微服务预分配固定数量的服务器并不符合成本效益。更好的方法是为-组微服务预留一-些服务 器实例,而不用预先分配。这样,根据需求,一组服务可以共享- -组可用的资源。这样做可以通过优化使用资源,将微服务动态移动到可用的服务器实例中。
例如,MI微服务有三个实例,M2微服务有一一个实例,M3微服务有一个实例,这些实例都是正在运行的。还有另一台服务器保持未分配。根据需求,未分配的服务器可用于任何微服务:MI、M2或M3。如果MI有更多的服务请求,那么未分配的实例将用于M1。当服务使用率下降时,服务器实例将被释放并移回到池中。之后,如果M2需求增加,则可以使用M2激活相同的服务器实例。
总结起来,使用自动扩展有以下好处。
1.提高了可用性和容错能力
由于服务是存在多个实例的,即使其中-一个实例失败,另一个实例也可以接管并继续为客户提供服务。这种故障转移对消费者来说是透明的。如果此服务的其他实例不可用,则自动扩展服务将会识别到该情况,并调用具有该服务实例的另一个服务器。随着整个实例的自动化,整个服务的可用性将高于没有自动扩展的系统。没有自动扩展的系统需要手动来进行添加或删除服务实例,这将在大型部署中难以管理。
例如,假定M1服务的两个实例正在运行。如果流量增加,在正常情况下,现有实例可能会过载。在大多数情况下,整套服务将被堵塞,导致服务不可用。而在自动扩展的情况下,可以快速创建一个新的M1服务实例。这将会平衡负载并确保服务可用性。
2.增加了可伸缩性
自动扩展的关键优势之一是水平扩 展性。自动扩展允许用户根据流量模式自动选择放大或缩小服务。
3.具有最佳使用率,并节约成本
在即付即用模式中,计费基于实际的资源利用率。通过自动扩展方式,实例将根据需求启动和关闭。因此,资源得到最佳利用,从而节省成本。
4.优先考虑某些服务或服务组
使用自动扩展可以考虑不同服务的优先级。这将通过从低优先级的服务中移除实例并将其重新分配给高优先级的服务来完成。这也将消除高优先级服务因资源紧张而得不到执行,而低优先级服务大量使用资源的情况。