Service Mesh Virtual Meetup 是 ServiceMesher 社区和 CNCF 联合主办的线上系列直播。本期为 Service Mesh Virtual Meetup#1 ,邀请了四位来自不同公司的嘉宾,从不同角度展开了 Service Mesh 的应用实践分享,分享涵盖来自陌陌和百度的 Service Mesh 生产实践,Service Mesh 的可观察性和生产实践以及与传统微服务中可观察性的区别,还有如何使用 SkyWalking 来观测 Service Mesh。
本文根据5月13日晚,百度高级工程师罗广明的主题分享《Service Mesh 高可用在企业级生产中的实践》整理。文末包含本次分享的视频回顾链接以及 PPT 下载地址。
Service Mesh 在企业落地中有诸多挑战,当与传统微服务应用共同部署治理时可用性挑战更为严峻。本次分享将以 Service Mesh 与 Spring Cloud 应用互联互通共同治理为前提,着重介绍基于 Consul 的注册中心高可用方案,通过各种限流、熔断策略保证后端服务的高可用,以及通过智能路由策略(负载均衡、实例容错等)实现服务间调用的高可用。
微服务是时下技术热点,大量互联网公司都在做微服务架构的推广和落地。同时,也有很多传统企业基于微服务和容器,在做互联网技术转型。而在这个技术转型中,国内有一个现象,以 Spring Cloud 与 Dubbo 为代表的微服务开发框架非常普及和受欢迎。近年来, 新兴的 Service Mesh 技术也越来越火热,受到越来越多开发者的关注,大有后来居上的趋势。
在听到社区里很多人谈到微服务技术选型时,注意到他们讨论一个非此即彼的问题:采用 Spring Cloud 还是以 Istio 为代表的 Service Mesh 技术?然而这个答案并非非黑即白、非你即我,一部分应用采用 Spring Cloud,另一部分采用 Service Mesh(Istio)是完全可能的。今天我就和大家一起来讨论这个问题。
首先,我们来看一下 Spring Cloud 这个传统侵入式微服务框架。它包含以下优点:
特别感谢 Netflix ,这家很早就成功实践微服务的公司,几年前把自家几乎整个微服务框架栈贡献给了社区,早期的 Spring Cloud 主要是对 Netflix 开源组件的进一步封装。不过近两年,Spring Cloud 社区开始自研了很多新的组件,也接入了其他一些互联网公司的优秀实践。
接下来,我们简单看一下 Service Mesh 框架。它带来了两大变革:微服务治理与业务逻辑的解耦,异构系统的统一治理。此外,服务网格相对于传统微服务框架,还拥有三大技术优势:可观察性、流量控制、安全。服务网格带来了巨大变革并且拥有其强大的技术优势,被称为第二代“微服务架构”。
然而就像之前说的软件开发没有银弹,传统微服务架构有许多痛点,而服务网格也不例外,也有它的局限性。这些局限性包括:增加了链路与运维的复杂度、需要更专业的运维技能、带来了一定的延迟以及对平台的适配。
更多关于 Spring Cloud 与 Service Mesh 的优缺点与比较,请阅读 Istio-Handbook [Service Mesh 概述]。
前面提到过,对于传统微服务框架 Spring Cloud 与新兴微服务框架 Service Mesh,并非是个非黑即白,非你即我,延伸到微服务与单体架构,它们也是可以共存的。
也可以将其与混合云相类比,混合云中包含了公有云、私有云,可能还有其它的自有基础设施。目前来看,混合云是一种流行的实践方式;实际上,可能很难找到一个完全单一云模式的组织。对多数组织来说,将一个单体应用完全重构为微服务的过程中,对开发资源的调动是一个很严峻的问题;采用混合微服务策略是一个较好的方式,对开发团队来说,这种方式让微服务架构触手可及;否则的话,开发团队可能会因为时间、经验等方面的欠缺,无法接受对单体应用的重构工作。
混合微服务出现的原因是为了更好的支持平滑迁移,最大限度的提升服务治理水平,降低运维通信成本等,并且可能会在一个较长的周期存在着。而实现这一架构的前提,就是各服务的“互联互通”。
要想实现上述“混合微服务架构”,运行时支撑服务必不可少,它主要包括服务注册中心、服务网关和集中式配置中心三个产品。
传统微服务和 Service Mesh 双剑合璧(双模微服务),即“基于 SDK 的传统微服务”可以和“基于 Sidecar 的 Service Mesh 微服务”实现下列目标:
这里还包括对应用运行平台的要求,即两个体系下的应用,既可以运行在虚拟机之上,也可以运行在容器 /K8s 之上。我们不希望把用户绑定在 K8s 上,因此 Service Mesh 没有采用 K8s 的 Service 机制来做服务注册与发现,这里就突出了注册中心的重要性。
百度智能云 CNAP 团队实现了上述混合微服务架构,即实现了两个微服务体系的应用互联互通、平滑迁移、灵活演进。上述混合微服务架构图包括以下几个组件:
接下来主要看一下注册中心的服务注册和发现机制:
前面提到过,要想实现实现混合微服务架构,注册中心很关键。谈到注册中心,目前主流的开源注册中心包括:
我们注册中心选择了 Consul,Consul 包含了以下几个重要的功能:
上图是 Consul 官网提供的架构图。Consul 架构中几个核心的概念如下:
注册中心作为基础组件,其自身的可用性显得尤为重要,高可用的设计需要对其进行分布式部署,同时因在分布式环境下的复杂性,节点因各种原因都有可能发生故障,因此在分布式集群部署中,希望在部分节点故障时,集群依然能够正常对外服务。注册中心作为微服务基础设施,因此对其容灾和其健壮性有一定的要求,主要体现在:
Consul 使用 Raft 协议作为其分布式一致性协议,本身对故障节点有一定的容忍性,在单个 DataCenter中 Consul 集群中节点的数量控制在 2*n + 1 个节点,其中 n 为可容忍的宕机个数。Quorum size: Raft 协议选举需要半数以上节点写入成功。
Q1: 节点的个数是否可以为偶数个?
A2:答案是可以的,但是不建议部署偶数个节点。一方面如上表中偶数节点4和奇数节点3可容忍的故障数是一样的,另一方面,偶数个节点在选主节点的时候可能会出现瓜分选票的情形(虽然 Consul 通过重置 election timeout 来重新选举),所以还是建议选取奇数个节点。
Q2: 是不是 Server 节点个数越多越好?
A2:答案是否定的,虽然上表中显示 Server 数量越多可容忍的故障数越多,熟悉 Raft 协议的读者肯定熟悉 Log Replication( 如上文介绍,日志复制时过半写成功才返回写成功),随着 Server 的数量越来越多,性能就会越低,所以结合实际场景一般建议 Server 部署3个节点。
推荐采用三节点或五节点,最为有效,且能容错。
注册中心设计的一个重要前提是:注册中心不能因为自身的原因或故障影响服务之间的相互调用。因此在实践过程中,如果注册中心本身发生了宕机故障/不可用,绝对不能影响服务之间的调用。这要求对接注册中心的 SDK 针对这种特殊情况进行客户端容灾设计,『客户端缓存』就是一种行之有效的手段。当注册中心发生故障无法提供服务时,服务本身并不会更新本地客户端缓存,利用其已经缓存的服务列表信息,正常完成服务间调用。
我们在设计时采用同 Datacenter 集群内部部署3个 Server 节点,来保障高可用性,当集群中1个节点发生故障后,集群仍然能够正常运行,同时这3个节点部署在不同的机房,达到机房容灾的能力。
在云上环境,涉及多 region 环境,因此在架构设计设计时,我们首先将 Consul 的一个 Datacenter 对应云上一个 region,这样更符合 Consul 对于 Datecenter 的定义(DataCenter 数据中心是私有性、低延迟、高带宽的网络环境)。中间代理层实现了服务鉴权、多租户隔离等功能;还可以通过中间代理层,对接多注册中心。
云上环境存在多租户隔离的需求,即:A租户的服务只能发现A租户服务的实例。针对此场景,需要在 『中间代理层』完成对多租户隔离功能的实现,其主要实践思路为使用 Consul Api Feature 具备 Filtering 功能:
什么是高可用?维基百科这么定义:系统无中断地执行其功能的能力,代表系统的可用性程度,是进行系统设计时的准则之一。我们通常用 N 个9来定义系统的可用性,如果能达到4个9,则说明系统具备自动恢复能力;如果能达到5个9,则说明系统极其健壮,具有极高可用性,而能达到这个指标则是非常难的。
常见的系统不可用因素包括:程序和配置出 bug、机器故障、机房故障、容量不足、依赖服务出现响应超时等。高可用的抓手包括:研发质量、测试质量、变更管理、监控告警、故障预案、容量规划、放火盲测、值班巡检等。这里,将主要介绍通过借助治理策略采用高可用设计手段来保障高可用。
高可用是一个比较复杂的命题,所以设计高可用方案也涉及到了方方面面。这中间将会出现的细节是多种多样的,所以我们需要对这样一个微服务高可用方案进行一个顶层的设计。
比如服务冗余:
比如柔性化/异步化:
上面讲到的几种提高服务高可用的手段,大多需要从业务以及部署运维的角度实现。而接下来会重点介绍,可以通过 SDK/Sidecar 手段提供服务高可用的治理策略,这些策略往往对业务是非侵入或者弱侵入的,能够让绝大多数服务轻松实现服务高可用。
微服务之间一旦建立起路由,就意味着会有数据在服务之间流通。由于不同服务可以提供的资源和对数据流量的承载能力不尽相同,为了防止单个 Consumer 占用 Provider 过多的资源,或者突发的大流量冲击导致 Provider 故障,需要服务限流来保证服务的高可用。
在服务治理中,虽然我们可以通过限流规则尽量避免服务承受过高的流量,但是在实际生产中服务故障依然难以完全避免。当整个系统中某些服务产生故障时,如果不及时采取措施,这种故障就有可能因为服务之间的互相访问而被传播开来,最终导致故障规模的扩大,甚至导致整个系统奔溃,这种现象我们称之为“雪崩”。熔断降级其实不只是服务治理中,在金融行业也有很广泛的应用。比如当股指的波动幅度超过规定的熔断点时,交易所为了控制风险采取的暂停交易措施。
负载均衡是高可用架构的一个关键组件,主要用来提高性能和可用性,通过负载均衡将流量分发到多个服务器,同时多服务器能够消除这部分的单点故障。
以上治理规则在某种程度上可以在 Spring Cloud 与 Service Mesh 两个框架上进行对齐,即同一套治理配置,可以通过转换分发到 Spring Cloud 应用的 SDK 上以及 Service Mesh 的 Sidecar 上。可以由 Config-server 负责规则下发,也可以由 Service Mesh 的控制面负责下发,取决于具体的架构方案。
对于一个应用系统来说一定会有极限并发/请求数,即总有一个 TPS/QPS 阀值,如果超了阀值则系统就会不响应用户请求或响应的非常慢,因此我们最好进行过载保护,防止大量请求涌入击垮系统。限流的目的是通过对并发访问/请求进行限速或者一个时间窗口内的请求进行限速来保护系统,一旦达到限制速率则可以拒绝服务或进行流量整形。
常用的微服务限流架构包括:
常用的限流策略包括:
常用的限流算法包括:
滑动时间窗口算法:
令牌桶算法:
漏桶算法:
令牌桶算法和漏桶算法,在某些场景下(内存消耗、应对突发流量),这两种算法会优于时间窗口算法成为首选。
断路器模式是微服务架构中广泛采用的模式之一,旨在将故障的影响降到最低,防止级联故障和雪崩,并确保端到端性能。我们将比较使用两种不同方法实现它的优缺点: Hystrix 和 Istio。
在电路领域中,断路器是为保护电路而设计的一种自动操作的电气开关。它的基本功能是在检测到故障后中断电流,然后可以重置(手动或自动),以在故障解决后恢复正常操作。这看起来与我们的问题非常相似:为了保护应用程序不受过多请求的影响,最好在后端检测到重复出现的错误时立即中断前端和后端之间的通信。Michael Nygard 在他的《Release It》一书中使用了这个类比,并为应用于上述超时问题的设计模式提供了一个典型案例,可以用上图来总结。
Istio 通过 DestinationRule 实现断路器模式,或者更具体的路径 TrafficPolicy (原断路器) -> OutlierDetection,根据上图模型:
与上述公称断路器相比,有两个主要偏差:
Hystrix 提供了一个断路器实现,允许在电路打开时执行 fallback 机制。最关键的地方就在 HystrixCommand 的方法 run() 和 getFallback():
Spring Cloud 是建立在 Spring Boot 之上的框架,它提供了与 Spring 的良好集成。它让开发者在处理 Hystrix 命令对象的实例化时,只需注释所需的 fallback 方法。
实现断路器的方法有两种,一种是黑盒方式,另一种是白盒方式。Istio 作为一种代理管理工具,使用了黑盒方式,它实现起来很简单,不依赖于底层技术栈,而且可以在事后配置。另一方面,Hystrix 库使用白盒方式,它允许所有不同类型的 fallback:
它还提供了级联回退(cascading fallbacks)。这些额外的特性是有代价的:它需要在开发阶段就做出fallback 的决策。
这两种方法之间的最佳匹配可能会依靠自己的上下文: 在某些情况下,如引用的服务,一个白盒战略后备可能是一个更好的选择,而对于其他情况下快速失败可能是完全可以接受的,如一个集中的远程登录服务。
常用的熔断方法包括自动熔断与手动熔断。发生熔断时也可以选择 fail-fast 或者 fallback。这些用户都可以基于需求灵活使用。
最后,我们来看一下智能路由带来的高可用。智能路由这里包括(客户端)负载均衡与实例容错策略。对于 Spring Cloud 框架来说,这部分能力由 Ribbon 来提供,Ribbon 支持随机、轮询、响应时间权重等负载均衡算法。而对于 Service Mesh 框架,这部分能力由 Envoy 提供,Envoy 支持随机、轮询(加权)、环哈希等算法。为了实现两套系统的规则统一对齐,可以采用其交集。
而容错策略包括:
Istio 支持重试策略配置,而 fail-fast 即对应与重试次数为0。
微服务的高可用是一个复杂的问题,往往需要从多个角度去看,包括:
以上就是本期分享的全部内容。
直播回放地址: https://www.bilibili.com/video/BV1WT4y1u73W
分享 PPT 下载地址: https://github.com/servicemesher/meetup-slides/tree/master/2020/05/virtual