前言
在微服务架构中,帮助开发者快速构建应用的脚手架技术无疑是非常重要的。以SpringBoot为代表的基底技术在继承了Spring框架思想的同时将简洁便利、约定优于配置、开箱即用等特性进一步发扬光大。然而仅仅依靠SpringBoot还不足以支撑微服务架构应对服务高可用、服务动态配置、服务高可扩展、服务负载均衡、服务容错与隔离等非功能需求,我们还需要相关基础设施提供服务治理及管控能力。
Pivotal公司的SpringCloud可以说是JVM平台上微服务治理框架的集大成者。本章我们将详细讲解服务注册中心、服务配置中心、微服务网关三个微服务运行时的关键支撑系统。另外,将介绍SpringCloud组件依赖Ribbon及Hystrix模块如何实现负载均衡和熔断管理等。
服务注册与发现
在云原生架构下,微服务需要具备极强的动态性及可扩展性,而服务注册与发现机制正是微服务可扩展性的基础。在微服务体系中,服务注册中心是微服务的核心模块,它是微服务架构中对服务的位置信息、心跳信息、元数据信息进行管理的重要基础设施。服务注册中心通过中心化、动态化的方式管理众多微服务实例。
服务注册与发现原理
在传统的应用系统中,基于硬编码方式对外提供服务地址的方式存在诸多问题,在服务扩展、服务高可用、服务升级方面,如果使用硬编码方式将使服务调用方与服务提供方产生紧耦合问题。
在早期的分布式系统架构中,使用DNS(DomainNameServer,域名服务器)协议作为服务发现机制,它是实现服务调用方与服务提供方解耦的一种简单有效的方式。DNS协议是一个“古老”的协议,也是最基本、最通用的协议之一。几乎所有操作系统底层都支持DNS协议,基于DNS协议的服务发现具备非常好的通用性,几乎使用所有编程语言都可以无缝接入。DNS可以让我们的一个服务名称与一组IP地址关联,或者与一个负载均衡器关联,实现多实例的分发。但是基于DNS协议的服务发现机制还是存在灵活性差、无法定制、端口及语言框架等问题。
在云原生范式的微服务架构中,服务的地址信息、服务的描述信息、服务的健康状态、服务的心跳信息、服务的版本、服务的元数据都是服务注册中心关心的初始数据。所以越来越多的基于“私有”协议的服务注册中心涌现出来。后面我们会详细介绍一些目前比较流行的微服务架构的服务注册中心。
下面我们首先来了解一下服务注册与服务发现两者之间的关系。
服务注册是生产者将自己的服务元信息上传到服务注册表中的过程,而服务发现是一个消费者通过服务注册表实时获取可用生产者服务信息的过程。
服务注册方式
●自注册:顾名思义就是服务提供方在启动服务时自己把提供服务的IP和端口发送到注册中心,并通过心跳的方式维持健康状态;服务下线时,自己把相应的数据删除。典型的案例是使用Eureka客户端发布微服务。
●第三方注册:存在一个第三方的系统负责在服务启动或停止时向注册中心增加或删除服务数据。NetflixPrana就是一款第三方注册系统,可与非JVM应用共同运行,并利用Eureka为该应用注册。
●注册中心主动同步:是指将注册中心和调度或发布系统打通,注册中心主动同步最新的服务IP列表。在Kubernetes体系中,CoreDNS订阅APIServer数据就是采用这种方式实现的。
服务发现方式
●客户端服务发现
在向某一服务发送请求时,客户端会通过查询服务注册表(ServiceRegistry)获取该服务实例的位置,该注册表中包含所有服务的位置。下图展现了这种模式的结构。
客户端服务发现拥有以下优势:
○相较于服务端服务发现,活动部件与网络中转数量更少。
○客户端可以根据自己的策略实现负载均衡,有掌控优势。
客户端服务发现存在以下弊端:
○客户端与服务注册表耦合。○需要为应用程序中使用的每种编程语言或框架建立客户端服务发现逻辑。举例来说,NetflixPrana就为非JVM客户端提供了一套基于HTTP代理的服务发现方案。
●服务端服务发现
在向某一服务发送请求时,客户端会通过在已知位置运行的路由器(或者负载均衡器)发送请求。路由器会查询服务注册表,并向可用的服务实例转发该请求。服务注册表也可能内建于路由器中。下图展现了这种模式的结构。
服务端服务发现拥有以下优势:
○相较于客户端服务发现,其客户端由于无须实现发现功能,对代码没有侵入,而且客户端只需要向路由器发送请求即可。
○可以解耦客户端与服务端的依赖关系。
服务端服务发现存在以下弊端:
○路由机制作为另一系统组件进行安装与配置,不仅需要具备一定的接入能力,还需要为其配置一定数量的副本。
○相较于客户端服务发现,服务端服务发现需要更多的网络跳转。
微服务注册中心技术选型
技术选型可以说是软件开发人员经常面临的问题,技术选型的首要原则是满足业务场景的需要,《人月神话》中提到软件的本质复杂性在于复杂的业务领域,而技术仅仅是辅助工具,技术选型解决的问题是将业务领域问题转换为软件实现。除此之外,从技术的层面上来说,我们还需要考虑如下关键因素。
●软件的成熟度及软件架构的完整性。不要盲目追求新技术,要采用成熟稳定的技术,在生产环境中经过长时间运行检验的技术可减小我们的使用风险。
●软件工程性方面。需要考虑公司人员擅长的技术,如果公司目前的业务系统大部分都使用Java相关技术,迁移到以Java为核心的服务框架或者技术工具会更加容易,且可以降低学习成本。
●社区活跃度。软件在开源之后,社区越活跃说明有越多的人