1 基于网关服务治理的研究与实践(一)微服务架构
1.1 微服务架构概念与优势
微服务的概念最早由Martin Fowler和 James Lewis 共同提出:微服务是一种架构风格,一个应用程序由多个服务单元组成;每个服务都运行在独立的进程中,服务可以独立部署;服务可以使用独立的开发技术体系构建,各服务单元之间松耦合;每个服务可以由一个独立的团队开发完成。
微服务架构是一种架构模式,也是一个分布式系统,它提倡按照业务将单一程序划分为不同的服务单元,服务之间相互协调、相互配合,服务与服务之间通过轻量级的通信机制互相沟通,通常是基于HTTP协议的Restful API。在应用开发方面,传统的企业系统架构通常将一个复杂的业务需求构建成一个单体应用,当单体应用变得越来越庞大甚至臃肿时,可能会导致新人培养周期长、交付周期长、可伸缩性差、可靠性等问题。相较于单体应用的不足,微服务架构解决的是快速迭代、高可靠和高可用等问题,将复杂的业务功能根据不同的业务划分为独立的微服务,降低服务之间的耦合性,进一步提高迭代速度和扩展能力,提升系统的可靠性和可用性,具体优势表现在:
(1)边界性
微服务将复杂庞大的单体应用分解成一组服务,可根据业务的边界确定服务边界,使每个服务边界清晰,互不影响。拆分后的微服务,降低了业务的复杂度,服务与服务之间的关系松散化,业务上下文独立。每个微服务都是一个高内聚、低耦合遵循单一职责原则的服务,都是一个完整的小规模的应用程序,各个微服务都专注于实现单一业务领域的功能,可以独立的开发测试、构建部署。每个微服务通过接口对外提供服务,服务之间的功能耦合度低,运行环境相互隔离,互不干扰,可并行执行发布的流程,提高快速迭代、持续交付能力。
(2)独立性
由于微服务都有独立的运行进程,因此每个微服务都可以做到独立部署。当微服务的业务功能发生需求变更时,无须编译部署整个应用,降低了对生产环境可能发生的风险,缩短应用交付周期。正是因为微服务的独立性,使微服务在扩展方面更加灵活,当应用出现瓶颈时,每个微服务可以根据实际需求进行独立扩展,实现对微服务的多节点部署,并使微服务持续部署成为可能。
(3)技术多样性
在微服务架构模式下,技术选型和数据管理是去中心化的。技术选型,服务之间通过轻量级的通信机制互联互通,对于服务本身无须关注具体的技术平台,服务不受原有系统技术的制约,每个团队可以针对自身不同的业务需求和行业发展的现状,自由选择合适的语言、合适的工具和技术。数据管理方面,各个服务管理其自有的数据库,另外,每个微服务的业务数据独立,可以选择更合适的数据存储。因此在当某个服务的技术平台遇到短板时,需要对技术平台进行升级或替换,此时所产生的系统风险就较低,对系统整体的影响最小化。
(4)组织优化
根据康威定律,技术架构设计应与团队组织架构相适应。按照传统的单体系统架构组织团队方式,通常从技术的层面将团队划分为多个不同的职能团队,如前端开发、后端开发、UI设计团队、DBA团队等,当其中的一个服务需要升级或更新,就需要综合考虑并与各个团队沟通修改情况,增加了跨团队的沟通成本。微服务倾向于围绕服务边界建立和服务范围相匹配的跨职能团队,而并不是孤立的按技术架构来划分,采用不同的团队分割方法,针对于特定的业务领域完整的实现,包括数据持久化存储、接口定义、对象交互等跨专业领域的功能,一方面可以减少服务内部之间的消耗,另一方面,团队边界可以变得更加清晰。
相比单体式应用架构而言,微服务架构模式有诸多的优势,但也引发了其自身的一些问题与挑战。微服务应用是分布式系统,服务拆分增加了系统的可伸缩性与灵活性,也由此给系统开发、测试及故障排查带来了高度的复杂性;拆分后的服务数量急剧增多,服务之间的通信存在网络延迟、访问中断等不稳定性因素,对运维管理也是很大的挑战。虽然在引入微服务时碰到这些困难和挑战,而微服务架构便于开发、理解和维护,同时也有助于提高软件项目的开发效率、产品质量及提高整体业务的灵活性,在构建复杂应用方面仍具有很大的优势。
1.2 服务注册与发现
服务注册与发现是微服务架构中必不可少的最核心、最基础的组成部分,它主要解决服务之间的发现和调用问题。在微服务架构中,通过静态配置的方式手工维护服务实例清单,随着微服务的种类和数量的增多,将逐渐变得难以维护;另一方面,服务调用则需要知道目标服务实例具体的网络位置,而服务实例的网络地址是动态分配的,导致服务的网络位置变得不可预知,因此,需要服务发现机制来保持服务之间的正常通信。
服务注册中心是服务发现机制中不可缺少的部分,其提供服务发现及服务注册的能力,解耦了服务提供者和服务消费者之间的依赖关系,支持服务实例的动态伸缩。如图1-1 所示。服务注册中心主要包含三个部分:服务提供者、服务消费者、服务注册表,服务提供者启动时将自身信息注册到服务注册表,服务消费者从服务注册表获取服务提供者的信息后向服务提供者发起服务调用,服务注册表是服务发现的核心,是一个存储了服务实例的网络信息和监控状态的数据库,维护服务提供者的最新网络信息,并与服务提供者保持心跳及监控其存活状态,当服务提供者的实例发生变更时,服务注册表需要通知服务消费者变更。
图1-1 服务注册中心工作原理
服务注册是指将服务实例的网络信息和监控状态存储至服务注册表,通常有两种注册模式:一种是自注册模式,即服务实例自行注册到服务注册表,或从服务注册表中注销自己,每个服务实例主动向服务注册表上报网络信息和监控状态,为防止注册过期,一般通过实现发送心跳请求的方式以确定服务实例的存活;该模式实现简单,不依赖其它组件,但服务实例与服务注册表强耦合,需要在服务注册表为服务实例中使用到的不同的开发技术实现服务注册和注销功能。另一种是第三方注册模式,即服务实例不直接向服务注册表注册或注销,而是通过一个第三方的系统组件进行注册,该组件通过轮询部署环境或订阅事件的方式来跟踪正在运行的服务实例的变化,当其发现有新的可用的服务实例时,就会注册到服务注册表;该模式解耦了服务实例和服务注册表,不需要为每个不同的开发技术实现服务注册和注销功能,由第三方组件集中管理实现,但要求这个第三方组件必须保证高可用性,也增加了系统运维的复杂性。
服务发现机制是为了解决服务实例动态变化后被发现的问题,服务消费者通过该机制能够及时取服务提供者的信息,并建立服务实例与服务注册表之间的关联。服务发现机制有两种主要的服务发现模式:客户端发现模式和服务端发现模式(或代理模式)。客户端发现模式是由客户端主动请求查询服务注册表,并根据负载均衡策略决定可用的服务实例的网络地址,并从中选择一个可用的服务实例地址发送请求;该模式的优势是比较灵活、服务去中心化,服务客户端可自行制定负载均衡策略,缺点是服务客户端与服务注册表强耦合,需要为客户端使用到的不同的开发技术实现客户端服务发现功能,如图1-2 所示。
图1-2 客户端发现模式
服务端发现模式是基于服务端的负载均衡器实现的,客户端通过向负载均衡器发送请求,由负载均衡器请求查询服务注册表,并将请求路由到可用的服务实例;该模式的优势在于解耦了服务客户端与服务注册表之间的依赖关系,由负载均衡器提供服务,并增加了一次转发操作,也增加了一个系统故障点,使系统运维难度大大增加,对负载均衡服务可用性要求更高,如图1-3 所示。
图1-3 客户端发现模式
1.3 服务路由与负载均衡
在以微服务体系构建的系统中,可能有由几十甚至成百上千个微服务组成,调用方发起的一个WEB请求,最终会被一个服务实例所接收并处理。当服务越来越多时,就需要一种请求转发机制来确保客户端的请求能够正确的发送到特定的服务实例。
服务路由决定了服务消费者的调用目标,为服务调用提供单个入口点。服务消费者通过服务提供者的名称,在服务注册中心找到要调用的服务实例的地址列表,发起向目标服务实例的请求。为了将网络请求均衡的分配到后端服务器,负载均衡服务将从对应的服务实例的地址列表中,根据所设定的负载均衡策略和相应规则,从中选定一台可用的服务器执行请求,即服务的负载均衡。
负载均衡是微服务架构体系中的重要组成部分,在服务器大流量、高并发的情况下,它能够缓解网络压力及平均分摊后端服务器的处理压力、并行处理客户端的请求,对维持微服务架构的高可用、可扩展性、高性能、安全性等方面有至关重要的作用。常见的负载均衡策略有以下几种:
(1)随机策略
客户端请求随机分配到从服务器列表中选择的其中一台服务器。
(2)加权随机策略
每台服务器都设置了各自的权值,根据权重随机请求服务器。
(3)轮询策略
将客户端的请求按时间顺序轮流地分配到不同的服务器。这种算法简单也比较公平,每台服务器轮流进行服务,此种均衡策略适合每台服务器软硬件配置相同、请求相对均衡且处理能力相同的情况。
(4)加权轮询策略
根据每台服务器软硬件配置的不同、安装部署应用的不同及不同的处理能力,为每台服务器设置不同的权值,将请求顺序按权重分配到相应的服务器。为配置高、负载低的服务器配置更高的权重以处理更多的请求,给配置低、负载高的服务器配置较低的权重以降低服务器负载。
(5)最少连接策略
最少连接策略是指从现有的服务器列表中选择目前连接数或请求数最少的服务器处理当前的网络请求。由于服务器软硬件配置的不同,对客户端的请求处理能力也不尽一样,根据服务器当前处理情况,动态地将网络请求分配到正在处理请求数最少的服务器上,以最大限度的提高服务器的利用率。
(6)一致性哈希策略
当客户端多次请求服务器时,每次请求可能会被不同的服务器处理,但有时要求让同一用户的请求被同一服务器处理,解决方法是利用哈希算法根据某个条件定位到对应的服务器。
一致性哈希策略是指相同的请求参数总是发送到同一个服务提供者。与哈希算法不同,一致性哈希算法的引入了虚拟节点的实现。当某台服务提供者宕机时,原本发往该服务提供者的请求,基于虚拟节点,将请求平摊到其它可用的服务节点,并不会引起服务变动,解决了宕机和扩容造成请求命中率急剧降低的问题,从而确保了服务的负载均衡,并使服务保持一致的性能。
(7)最短响应时间策略
最短响应时间策略是根据每个服务供者最近一段时间内的响应情况,从多个服务提供者中选出调用成功且响应时间最短的服务提供者,并将请求优先分配给平均响应时间最短的服务提供者,一般情况下,服务的处理能力影响了响应时间的速度。
1.4 服务容错
微服务架构将应用拆分为微服务后,单个微服务发生故障的概率变小,故障影响范围也减少,但导致微服务的节点数量大大增加。由于服务与服务的调用是通过网络协议进行通信,服务之间互相依赖互相调用,而网络通信又是不稳定、不可靠的。微服务具有故障扩散的特点,如果某个调用的服务出现故障未得到及时的处理,故障扩散开来就会导致整个系统看起来有很多服务节点都存在故障,必然会影响整个系统的稳定性和健壮性,此时就需要微服务能够自动应对这种出错场景,及时进行处理。否则,如果服务节点一旦出现故障就需要人工处理,投入人力过大,处理速度慢;而服务一旦处理速度过慢,则故障就很快扩散。因此,在资源有限和不稳定网络的条件下,对拥有服务容错的能力至关重要。为了防止雪崩效应造成的故障扩散,常见的服务容错处理模式如下:
(1)超时重试
超时模式是根据预先设置的超时间中断服务调用,及时释放资源,避免无限等待引发资源耗尽的问题;重试模式一般与超时模式结合使用,利用重试来解决客户端请求失败的情况,可通过设置请求超时时间和记录请求次数来决定是否需要进行重试操作,适于用对下游服务强依赖的场景。
(2)限流
限流是指在一段运行时间内,通过预先指定的策略削减流量,使落到后台服务的请求在其最大可以承受的请求量和处理能力范围之内。限流模式是保证微服务架构能够稳定运行的不可或缺的一部分,通过限流机制可以控制请求访问量,并能够过滤掉产生流量峰值的用户或后台服务实例,防止突增的流量对后台服务实例带来的冲击,进而避免后台服务出现过载、资源耗尽的情况,提高后台服务的稳定性。常用的限流模式有控制并发和控制速率,控制并发主要是限制并发的请求总数量,常用算法方法有:计数器、信号量;控制速率是限制并发访问的速率,常用算法有令牌筒、漏桶限流算法。
(3)熔断
在一个分布式的业务系统中,通常会有很多个服务组成,一个服务可能需要调用多个服务完成预期功能,而服务与服务之间的交互都是通过远程调用完成的,所以服务的稳定性易受到其它服务性能的制约。当调用链中的服务发生异常,服务响应时间过长或无法响应时,就会出现服务调用失败的情况,有些服务为了保证整体系统的可用性和一致性,引入了重试机制,更加加剧了调用失败的严重性,进而导致大量的请求等待,阻塞了重要的系统资源,直至消耗资源殆尽使服务不可用,服务不可用会使其它依赖的服务也不可用,这样循环往复,最终整个系统崩溃,即服务雪崩。
熔断模式是指服务消费者侦测到服务提供者发生错误或不可用时,为了保护自己及整个系统的可用性,立即返回错误,防止不断的尝试但仍发生相同的错误,不再调用目标服务。当检测被调用的服务可能恢复时,可在一段时间后再去尝试调用,恢复调用链路。熔断是应对微服务系统雪崩效应的一种服务链路自我保护策略,它能够使系统同时具备快速失败和无缝恢复的能力,减少了对系统资源的浪费,为保证系统的可用性和平稳运行起到关键性作用。
(4)失效转移
当调用服务发生异常或不可用时,如果有备份服务,将请求重定向到另一个可用的服务实例;同时可能是个别服务存在问题,采用重试的方法,并限定重试次数防止无限重试;或采用快速失败的策略,直接返回空值或缺省值,使服务出现故障后也能够优雅的运行,不影响用户体验。
(5)舱壁隔离
舱壁隔离模式借鉴了造船行业舱壁的概念,通过隔离每个服务远程调用的系统资源,即将依赖服务的调用分配到一个独立线程池中进行隔离,防止因某个服务调用的故障导致整个系统的不可用。该模式可以有效保护关键的系统资源不被耗尽,避免服务雪崩影响整个系统,增加微服务的健壮性。
服务容错机制更好的体现了微服务架构的容错性,通过超时重试、限流、熔断和舱壁隔离等措施构建稳定可靠的微服务,使微服务具有自我恢复的能力,提高微服务架构的稳定性和良好的用户体验。
1.5 服务安全
单体应用被拆分为若干个微服务后,每个微服务分别部署在不同的服务器,每个服务实例都需要对请求进行身份验证和访问控制,并且业务数据也被分散的存储在各个微服务的实例上,这不仅增加了系统的复杂度,也使安全问题也越来越突出。在服务通信上,服务之间的访问都是通过轻量级的通信机制实现,使微服务之间的通信内容被暴露出来;在服务接入上,接入方不但有前端应用与后台服务的交互,也有服务与服务之间的直接通信,微服务架构下的各个微服务内部之间相互信任,使服务之间可以任意访问;在业务数据上,不同的数据也有相应的操作权限,对于敏感的业务数据只允许部分微服务可以有权限访问。从服务通信、服务接入和业务数据上发现微服务架构存在的安全性问题,因此,需要通过一些服务安全措施来保证系统和业务数据的安全性,主要从传输安全、接入安全及数据安全三个方面进行考虑:
(1)传输安全
传输安全是指对传输过程中的数据进行加密,确保在流转数据的安全性、完整性和不可篡改性。在微服务架构体系中,服务与服务之间采用RESTful轻量级协议通信,在网络链路传输过程中,可能会造成请求内容被窃听篡改和破坏。通过对请求和响应数据进行加密和解密,减少在传输过程中被窃取的风险;数据完整性通常采用数字摘要算法实现,对传输内容进行签名及验签,从而增强信息的完整性、保密性和可靠性。
(2)接入安全
接入安全是确定请求者身份的合法性及对资源访问权限的鉴定。通常微服务架构根据业务细粒度将应用拆分为多个职责单一的微服务,每个微服务都可以对外部提供接口调用,也都需要对外部请求进行安全访问控制,从整个系统架构层面上,无法做到快速接入和统一控制。此时,可通过服务网关来保证服务的接入安全,所有的用户请求、接口调用均先通过服务网关,由服务网关统一对外部请求进行身份验证、访问授权、权限验证、资源保护、防攻击等。
(3)数据安全
数据安全是指采用加密技术对数据主动加以保护,防止数据被非法窃取、泄露及人为篡改。数据加密是保护数据在传输、存储和使用上安全的最行之有效的方法,对于需要落地的敏感数据采用可靠的加密算法进行加密存储,如用户姓名、交易密码、手机号码、银行卡等,以确保数据存储的安全性和保密性。
1.6 挑战
当业务系统微服务化后,也面临着诸多的问题需要解决,本系列文章主要从服务治理的角度分析微服务带来的挑战,请参考下一节内容介绍。