「回忆2022,展望2023,我正在参与2022年终总结征文大赛活动」

紧接上一篇,服务化结构落地的挑战和中心需求,那么依据这些中心诉求,咱们整个的微服务结构的模型是怎样?又该具有哪些中心的办理才干呢?经过本文来一一知晓!

微服务系列 2:微服务化框架的模型和治理能力设计

一、服务办理的了解

跟着互联网的开展和容器化的开展,更进一步的推动了微服务化的建造,在微服务系统下,咱们的服务办理,首先要做的便是针对咱们许多的服务怎样更好的进行办理,确保咱们系统在运行进程中能够主动化的发现问题并主动处理一些问题,然后使咱们的系统愈加的安稳。而这些办理的战略,至少要包含服务的限流、降级、容错,以及服务的弹性伸缩、灰度发布,还有主动化的运维。

服务办理与管控包含几大块:服务的办理、服务的监控、服务的可用性保证

  1. 服务的办理: 服务供给方的办理、服务运用方的办理、服务依靠的办理、服务的调用办理、服务的注册和发现、服务的布置和升级、服务的版别化办理
  2. 服务的监控:数据收集、数据处理、链路盯梢、白盒化的报表展示、系统级的监控
  3. 服务的可用性: 容错(Failover、Failfast)、负载均衡、过载维护、服务降级、频率约束

服务化结构的中心才干,括:RPC、服务发现与注册、负载均衡、容错、熔断、限流、降级、权限、全链路日志盯梢也是归于服务办理的范畴之内,当然服务办理不仅仅包含这些中心才干,还包含各种办理,结构要做的便是全套服务,运用只管定心接入运用,全部办理相关的都由结构去完成。

二、微服务架构模型

在我前面一篇文章《微服务化结构落地的挑战和中心需求》中,我梳理了微服务化结构落地的一些挑战和中心需求,那么针对这些中心需求,咱们看看微服务要完成那些中心才干,也便是将上述需求进行完成,完成的时分依据现有的技能计划来进行笼统和共同,终究就能够构成咱们的微服务结构。我将我了解的微服务架构模型分为如下三部分:

  • 中心才干,这个是结构必须要完成的,并且是任何一个服务化结构必备的才干

  • 扩展才干,这个是能够经过结构的插件化进行扩展的支撑,当然,结构本身也能够支撑,可是从我个人的了解上来看,这个经过外部组件进行扩展,会愈加符合全体的规划

  • 办理渠道,这个是环绕整个服务化结构、事务系统、开发流程所需求依靠的一些根底渠道,这些渠道能够更好的协助咱们进行服务的发布和上线,以及上线后的办理

微服务系列 2:微服务化框架的模型和治理能力设计

三、微服务结构的办理才干规划

3-1、微服务结构的中心才干

微服务需求供给的中心才干包含:微服务架构模型中通讯的根底协议RPC、服务发现与注册、负载均衡、容错、熔断、限流、降级、弹性扩缩容等

服务间通讯:RPC

在微服务架构中,服务之间的通讯,一般都是经过 长途拜访 的方法来进行。长途拜访的通讯方法有许多中,包含:

  • 从通讯风格上, 一般有 REST,RPC 和 定制协议这三种方法
  • 从交互方法上,依照交互对象的数量能够分为一对一和一对多,依照应答回来的方法分为同步和异步。

RPC 是服务通讯的根底,假如没有共同的 RPC 结构,各个团队就需求完成自己的一套接口协议界说、序列化、反序列化、网络结构、服务办理等重复作业,因而能够说,微服务的中心便是要有一个共同的 RPC 结构,共同一套 RPC 是微服务化首先要处理的问题。经过共同的 RPC 结构协议,能够共同咱们的接口界说,削减接入和学习的本钱。一起,假如咱们是依据已有的结构来完成,那么需求尽或许的确保兼容原有协议(比方依据 gRPC 的话,就要尽量确保兼容 gRPC 的接口协议)

业界可选的 RPC 结构有许多,比方 dubbo/dubbox,motan,thrift,grpc,Karyon/Ribbon等,在我之前的公司,咱们推广服务化结构的时分,是挑选了 gRPC 作为咱们的根底结构,然后依据 gRPC 丰厚了许多服务办理的战略,全体线上运行良好,并且有较多事务接入。

服务注册与发现

微服务架构下,咱们的事务都是由一系列独立的微服务组成,那么这些微服务之间怎样才干发现互相?这就要求微服务之间存在一种发现的机制。这个机制,叫做服务发现,服务发现的中心功用便是服务注册表,注册表记载了全部的服务节点的装备和情况,每个微服务发动后都需求将自己的信息注册到服务注册表,然后由微服务或许负载均衡系统到服务注册表查询可用服务。

服务端发现和客户端发现形式

在规划上,服务发现机制的规划有服务端发现和客户端发现两种完成方法。

  • 服务端发现形式(server-side):能够经过 DNS 或许带 VIP 的负载均衡来完成。

    • 长处是对客户端无侵入性,客户端只需求简略的向负载均衡或许服务域名主张恳求,无需联系服务发现的详细细节,也不用引进服务发现的逻辑
    • 缺陷是不灵活,不便利难异化处理;并且一起需求引进一个共同的负载均衡器。
  • 客户端发现形式(client-side):需求客户端服务注册中心中查询服务地址列表,然后再决议经过哪个地址恳求服务。

    • 灵活性更高,能够依据客户端的诉求进行满意本身事务的负载均衡,可是客户端需求引进服务发现的逻辑,一起依靠服务注册中心
    • 常见服务注册组件包含:zookeeper、etcd、Consul

在我从前的项目中,咱们是经过客户端发现形式来规划的,咱们会把这个才干集成在微服务结构里边,然后微服务结构在发动的时分,会将自己服务的信息注册到注册中心,注册中心咱们当时选用的是 ETCD。

服务注册和分析的共同性要求

服务注册和服务发现,在完成时依据对共同性要求的不同,分成两个门户:

  1. 强共同性

    • 比较常见的分布式共同性协议是 PAXOS 协议和 Raft 协议。相比 PAXOS 而言,Raft 协议易于了解和完成,因而最新的分布式共同性计划大都挑选 Raft 协议。
    • zookeeper 选用的是 PAXOS 协议,consul 和 etcd 选用的是 Raft 协议。
  2. 弱共同性

    • 假如对共同性要求不高,能够挑选以 DNS 为根底的计划。弱共同性计划比较少,一般多用于 REST 或许 HTTP + json / web service 等简略场合

尽管计划众多,可是对于普通用户的大多数场景而言,一般互联网公司主张从 zookeeper、etcd、consul 这三个干流计划中挑选,我之前的规划里边,咱们挑选的便是 etcd。

服务负载均衡

路由算法

服务负载均衡,一般情况下,是会和服务发现放在一起规划的,因为服务发现后,紧接着,便是要对服务进行路由,也便是服务的负载均衡,他们一般是作为一个全体系统来规划。尽管服务发现机制有服务端发现和客户端发现两种完成方法,可是无论放在哪里完成,针对服务进行路由,也便是负载均衡的中心的功用便是路由算法。常见的路由算法有:随机路由、轮询路由、最小压力路由、最小衔接数路由等。

现在微服务结构中,大都是在客户端发现形式(client-side) 来完成服务路和负载均衡,一般也都会支撑常见的负载均衡战略,如随机,轮训,hash,权重,衔接数【衔接数越少,优先级越高】。

心跳检测与去除

咱们要对服务进行负载均衡的话,有一个先决条件,便是咱们要路由的服务,必定是可用的,怎样确保服务可用,那么就需求进行心跳检测与去除:进行心跳检测,每个 N 秒检测一次,超越 M 次心跳连不上就进行去除。这样的话,就能够确保咱们路由的服务都是正常的。

多机房路由

假如服务布置在多个不同的机房,那么咱们路由的时分,一般的战略便是优先调用本地机房,失利重试也是本机房调用,假如本地机房没有可用节点则路由到其他机房。一起能够添加一个开关操控是否 failover 到长途机房。

服务容错

负载均衡和容错是服务高可用的重要手法。服务容错的规划在业界有个根本原则,便是“Design for Failure”。常见的服务容错战略如恳求重试、限流、降级、熔断等战略

超时与重试

超时是一种最常见的服务容错形式,只需涉及到网络调用,那么就有或许因为网络问题、依靠服务问题,导致调用的时分呈现恳求超时,一般情况下,咱们都会对每个恳求设置好超时时刻(一般接口不应该超越 1s),假如超时未回来,那么就会断开衔接,然后能够做对应的处理,比方回来失利、释放衔接、释放资源等。假如不做超时处理,那么或许会导致恳求一向卡在,然后一向占用系统资源,然后使得整个系统资源耗尽,或许用户一向刷不到数据。

重试,是指下流犯错(不管是真的犯错,仍是超时)的时分进行运用,经过重试能够较好的确保数据的可靠性,尤其是当下流有网络波动导致超时的场景下,会比较有用。重试的规划,有几个要害:

  • 重试的次数,必定要有一个最大值,经过必定的重试次数,仍是拿不到正确的数据,那么就应该回来过错,而不能一向重试,
  • 重试的时刻距离,需求设置,不能不停的重试,避免因为重试过多、过快导致系统担负增大,重试的时刻战略,咱们一般都会引进Exponential Backoff 的战略,也便是所谓的 “指数级退避”。在这种情况下,每一次重试所需求的 sleep 时刻都会指数添加。这其实和 TCP 的拥塞操控有点像。
服务限流

限流和降级都是用来确保中心服务安稳性的有用战略。限流是指约束每个服务(或许接口)的最大拜访量,超越这个阈值就会被回绝,是从用户拜访的恳求量量去考虑问题;降级是指高峰期对非中心的系统进行降级然后确保中心服务的可用性,是从系统功用的优先级角度考虑问题。

限流的意图是为了确保咱们的系统不过载,当系统流量增大的时分,经过限流,能够确保能够在系统可承受的压力之下安稳运行,否则,一旦过载则会导致整个系统不可用。在咱们实践运用中,到处都能够看到限流的一些战略场景,比方 Nginx 的 limit_conn 模块用来约束最大并发衔接数、limit_req 模块用来约束每秒平均速率。

常见的限流方法能够分为两类:依据恳求限流和依据资源限流。

  • 依据恳求限流。从外部系统的拜访恳求量的角度来考虑限流,常见的方法有:约束总量、约束时刻量。
  • 依据资源限流。从内部系统的运用资源的角度来考虑限流,找到系统内部影响性能的要害资源,对其运用上限进行约束。常见的内部资源有:衔接数、文件句柄、线程数、恳求队列等。

限流的维度和等级首要能够分为以下几类:服务等级维度的限流、接口等级维度的限流、事务细粒度等级维度的限流。

  • 服务等级维度的限流、接口等级维度的限流首要意图是维护咱们的系统,避免服务过载。

  • 事务细粒度等级维度的限流。首要意图是防刷,也是避免单用户或占用过多处理才干,影响其他用户。便是咱们依据事务内部的详细维度去限流,比方咱们能够经过 APPID 和 UID 这两个常见的事务维度。appid 便是对应某一类恳求或许一个事务类型,UID 便是对应一个仅有的用户。

服务降级

首先,降级之前,必定是要先限流,限流之后,系统仍是或许存在问题,才考虑降级。一起,降级不仅仅是开发人员的工作,还需求和产品人员交流和协商降级后的处理以及对应的作用。

降级规划(Degradation)实质是为了处理资源缺乏和拜访量过大的问题,当资源和拜访量呈现矛盾的时分,在有限的资源下,为了能够扛住许多的恳求,咱们就需求对系统进行降级操作。降级是指咱们划分好系统的中心功用和非中心功用,然后当咱们的系统超越最大处理才干之后,直接封闭掉非中心的功用,然后保证中心功用的可用。封闭掉非中心的功用后能够使咱们的系统释放部分资源,然后能够有资源来处理中心功用。

熔断规划

当下流服务呈现反常的时分(包含犯错、超时),一般咱们会进行短时刻且少数的重试操作,可是假如重试几次仍然无法处理,那么咱们也不能一向重试,这样会给下流带来更大的压力。

熔断,便是在重试、限流等战略执行之后,仍是无法处理的情况下的别的一种维护系统的战略手法,经过熔断,能够较好的维护好下流服务。熔断最重要的价值在于约束毛病影响规模,经过熔断削减或回绝恳求然后有利于下流系统的康复。

熔断系统规划的思路便是环绕熔断的三个情况来规划,一般咱们经过三个模块(反常恳求计算模块、熔断勘探康复模块、熔断记载和报警模块)来规划,首要的流程便是,在 Close 情况下,当咱们的恳求失利 N 次后,在 X 时刻不再继续恳求,完成熔断,进入 Half-Open 情况;与此一起,在 X 时刻后康复 M% 的恳求,假如 M% 的恳求都成功,则康复到正常情况,进入 close 情况,否则再熔断 Y 时刻,依此循环。假如一向无法康复,那么能够直接进入 Open 情况。

熔断和降级这两个战略,看着比较像,字面的意思上来看都是要快速回绝掉恳求。可是他们是两个维度的规划,降级的意图是应对系统本身的毛病,而熔断的意图是应对咱们系统依靠的外部服务毛病的情况。

集群容错

微服务化后,服务或许会布置到多个不同的机房,也便是或许会布置到多个不同的集群上,为此,就有集群容错一说,集群容错里边,咱们常见的两个战略是

  • failfast 战略,快速失利,只主张一次调用,失利立即报错。规划的时分需求留意

    • 操控超时时刻的判别和记载:衔接超时、呼应超时
  • failover 战略,失利主动切换,当呈现失利,重试到其他集群的服务

    • 优先调用本地机房,失利也是本机房调用
    • 默许不 failover 到长途机房,开关开启的时分才启用必定份额的 failover 战略调用到长途机房
    • 需求依据过错码来区分不同的呼应信息决议是否重试,比方404 400等情况是不需求重试的

弹性扩缩容

弹性扩缩容就要求运用服务规划为无情况模型,一般微服务结构无法完成弹性扩缩容,还需求配合其他的技能如容器技能(Kubernetes)、云服务技能等,这样才干完成弹性。

这儿更多的是结合其他才干比方 K8s,特意单独提出来,是为了说明这个的重要性。

3-2、微服务结构的扩展才干

API 接入层网关

微服务需求一个共同的 API 网关,负责外部系统的拜访操作。API 网关是外部系统拜访的进口,全部的外部系统接⼊内部系统都需求经过 API 网关,咱们一般的后端服务,外网是无法直接拜访的,API 需求做一层处理,首要包含接入鉴权(是否允许接入)、权限操控(能够拜访哪些功用)、传输加密、恳求路由、流量操控等功用。全部 ok 后才干拜访到咱们的内网服务。

监控和告警

监控系统的开源代表作: Prometheus + Grafana,遵从 OpenMetrics 标准,根本数据格式分为 Gauge、Count、Summary、Histogram。在咱们之前的完成中,公司也是选用普罗米修斯【prometheus】+ dashboard(grafana) 来完成整套监控系统的。

需求收集、监控的目标项有如下:

  • QPS

    • 组合查询 ,节点 ,服务,region,接口,时刻 等
  • latency

    • 组合查询 ,节点 ,服务,region,接口,时刻 等
  • SLA

    • 指定时刻段内恳求成功且耗时低于X毫秒的恳求个数份额,API接口等级
  • 消费节点

    • 当时消费节点的情况,有多少个服务节点,健康情况,熔断情况等

装备系统

咱们的一个事务服务,一般,都会有一个对应的装备文件,并且,咱们需求尽或许的做到动态装备,而不是每次修改装备都要从头发布服务。比方说,咱们界说好一个 Elasticserach 的账号密码,那么这个最好的方法,肯定是在装备文件里边,和代码阻隔; 比方咱们界说一个域名前缀,而这个前缀有或许会改动;比方咱们界说一个恳求的重试次数,这些,主张都是经过装备文件来办理。

每个服务一个装备文件,微服务化后,许多服务,就会有许多装备文件,那么这些装备文件怎样共同办理,怎样读取,怎样发布,就需求一个装备系统,装备系统也需求逐步演进为主动化办理方向,因而就需求一个完善的共同的主动化装备中心。

日志系统

长途日志上报

日志的重要性不言而喻,每次服务出问题,用户出问题,咱们要查问题,必然要经过日志,而咱们的服务这么多,布置的机器这么多,咱们不能每次出问题之后,还要去每台机器上一个个的检索。为此,这个就必然需求能够将日志进行长途上报,然后共同收集和办理。

这儿,长途日志组件的代表作是 ELK 系统:Elasticsearch, Logstash, Kibana。 经过引进 ELK,咱们在代码里边,将日志上报,后续就能够经过 Kibana 去依据情况进行检索,然后拉取出对应的日志。

traceID

在微服务架构中,一个客户端恳求的接入,往往涉及到后端一系列服务的调用,怎样将这些恳求串联起来?业界常用的计划是选用大局流水号【traceID】串联起来。经过大局流水号【traceID】,从日志里边能够拉出整条调用链路。

traceID 需求在全部日志里体现,包含拜访日志、过错日志、正告日志等任何日志,仅有标识一个恳求。调用链上每个环节的进口都先判别是否存在 traceID ,假如没有 traceID 则生成一个仅有值,存在恳求上下文 context 中,输出日志的时分就能够把 traceID 打印并输出。然后调用其他服务的时分一起传递共同名称的header 给方针服务,方针服务处理恳求是有获取到 traceID 就设置到自己的恳求上线文,以此类推,整个恳求链条就都运用共同的 traceID。一起 APP 客户端也能够传递一个自己的恳求事务标识(或许不必定会仅有),服务端把传上来的恳求标识作为 traceID 的一部分

分布式链路追寻系统和 OpenTelemetry

一般公司的后端架构运用构建在不同的服务模块集上,或许是由不同的团队开发、运用不同的编程语言来完成、布置在多台服务器上。对于这种分布服务系统,传统查日志方法排查问题繁琐,用时较久。因而,需求一个东西能够梳理这些服务之间的联系,感知上下流服务的形状。比方一次恳求的流量从哪个服务而来、终究落到了哪个服务中去?服务之间是RPC调用,仍是HTTP调用?一次分布式恳求中的瓶颈节点是哪一个,等等。假如咱们需求盯梢某一个恳求在微服务中的完整途径就要引进咱们的分布式链路追寻系统了,现在业界分布式链路追寻系统根本上都是以 Google Dapper (中文版) 为蓝本进行规划与开发。

OpenTracing 拟定了一套渠道无关、厂商无关的Trace协议,使得开发人员能够便利的添加或替换分布式追寻系统的完成。在2016年11月的时分CNCF技能委员会投票接受OpenTracing作为Hosted项目,这是CNCF的第三个项目,第一个是Kubernetes,第二个是Prometheus,可见CNCF对OpenTracing背面可调查性的注重。比方大名鼎鼎的Zipkin、Jaeger都遵从OpenTracing协议。

然后时刻走到 2022 年,OpenTracing 都现已快要过期, 现在最优的是 OpenTelemetry。OpenTelemetry 的终态便是完成 Metrics、Tracing、Logging 的交融,作为CNCF可调查性的终极处理计划,OpenTelemetry 可观测性范畴的标准,OpenTelemetry 的三大数据模型如下:

  • **Tracing:分布式追寻,观测恳求调用链路。**供给了一个恳求从接收到处理完毕整个生命周期的盯梢途径,一般恳求都是在分布式的系统中处理,所以也叫做分布式链路追寻。

  • **Metrics:目标监控,监控服务质量情况。**供给量化的系统内/外部各个维度的目标,一般包含Counter、Gauge、Histogram等。

  • **Logging:服务日志,用来分析服务毛病。**供给系统/进程最精细化的信息,例如某个要害变量、工作、拜访记载等。

3-2、微服务系统下的办理渠道

服务编列办理渠道

在之前的文章里边,咱们谈到,微服务和容器化结合是必然趋势,在当下,容器化渠道根本都是选用 K8s ,那么依据 K8s 渠道,咱们的服务编列当然就需求环绕 K8s 来建造了。微服务结构 + K8s 容器渠道 是当今互联网事务的黄金标准

假如是选用公有云的话,那么服务编列的办理渠道,公有云现已帮你供给了。

假如是私有云的话,那么咱们也需求依据 K8s 来建立一套咱们自己的服务编列的办理渠道,用来协助开发人员更好的去发布服务、线上办理服务。这个渠道上的的功用能够包含:

  • 服务发布和办理
    • 灰度发布
    • 服务重启/停止
    • 支撑回滚
  • 服务登录
    • 登录到服务地点的容器里边
  • 服务扩缩容
    • 手动扩缩容
    • 主动扩缩容
  • 打通外部渠道
    • 如监控渠道、日志渠道
    • 如服务限流和降级渠道
  • 支撑 debug 办理东西
    • 比方能够动态检查 go 相关的 runtime 信息,或许 pprof 等

DevOps 渠道

微服务系统下,有许多的服务需求进行运维办理,包含测验、发布上线、灰度放量、扩缩容等,那咱们怎样合理的去处理好这些运维才干呢,这儿就必须要有一套主动化运维办理系统,而这套东西,在业界,有一个叫做 DevOps 的文明,依据 DevOps 能够便利快捷的完成 CICD。CI 便是继续集成,是一种质量反应机制,意图是尽快发现代码中的质量问题,CD 便是 继续布置,是指能够主动化、多批次、可控的完成软件布置,操控毛病的影响规模或便利轻松的处理毛病问题。经过 DevOps 的建造,能够完成软件出产流水线和软件运维主动化。

DevOps 渠道这儿,更多的集成代码办理渠道、流水线构建、单测测验、接口测验判别等。比方咱们开发完一个功用,那么代码首先要合入到 master,然后对代码进行一些检测,随后打 tag,结构镜像,最后发布。这一系列的流程,假如没有一个适宜的办理渠道,每个步骤都手动去处理的话,那么就会适当费事,并且耗时。

DevOps 渠道的一些主张和实战经历:

  • 代码分支合入 master 的时分,进行检测校验

    • 代码静态检查
    • 代码标准检查
    • 单测覆盖度检测
    • 接口测验检测
  • 检测经过后,能够合入 master 分支,然后主动打 tag,结构线上发布的镜像包

  • 镜像包结构完后,主动和服务编列办理渠道打通,推送镜像到服务编列办理渠道,主动触发发布流程

    • 发布流程需求有灰度的进程
    • 可随时中止和回滚

主动化测验渠道

微服务化会带来服务模块增多的问题,会在必定程度上带来开发本钱的提升,所以需求经过配套的东西链来削减服务化后的开发本钱。主动化测验渠道的建造,能够有助于咱们在开发测验阶段就尽或许的削减系统呈现的问题,供给一层保证。主动化测验渠道首要的意图是用来进行接口测验和接口拨测,后续也能够进一步去整合 流量录制和回放、全链路压测等相关功用。

主动化测验渠道的首要的意图便是确保你上线发布的服务是正常运行的,并且尽量做到主动发现问题而不是经过人工反应后才干知道问题。接口拨测这个工作,类似巡检,便是每个一段时刻,主动调用你的后端接口,假如呈现非预期的过错,那么就以为反常,能够进行告警。

因为这些都是根底功用,因而没有必要每个团队都各自搞一套,应该是公司内部共同搞一套这样的系统。

最后

  • 这篇文章首发在我微信大众号【后端系统和架构】中,点击这儿能够前往大众号检查原文链接,假如对你有协助,欢迎前往关注,愈加便利快捷的接收最新优质文章

引荐阅读

引荐阅读我的其他文章:

  • 《高并发架构和系统规划经历》

  • 《TCP 长衔接层的规划和 在 IM 项目中实战运用》

  • 《万字解读云原生年代,怎样从 0 到 1 构建 K8s 容器渠道的 LB(Nginx)负载均衡系统》

  • 《我终于共同了团队的技能计划规划模板》