关于后端:稳定性建设系列文章2依赖关系治理

36次阅读

共计 2430 个字符,预计需要花费 7 分钟才能阅读完成。

零碎高可用的根基

随着公司业务一直的倒退,零碎也在变得越来越简单。零碎的复杂度体现在:前端对后端的依赖,后端服务之间的依赖。在没有明确强弱依赖的前提下,咱们很难进行熔断、降级、限流的相干操作,也不能无效的对系统进行相干优化革新、继续推动零碎稳定性晋升。

强弱依赖的定义

在聊强弱依赖之前,咱们先看下公司的服务分级规范:

S1 外围 S2 次外围 S3 非核心 S4 其余
S1 级别:影响业务线外围业务流程,会影响用户应用
S2 级别:不波及外围主业务流程,服务不可用会造成大范畴用户体验降落。
S3 级别:不波及外围业务流程,利用不可用对用户简直无影响,如头像、批改材料等一些长尾边缘利用。
S4 级别:利用不可用对线上简直无影响,如经营后盾,如后盾经营策略

在这里,咱们对强弱依赖的定义即可得出:异样产生时,不影响外围业务流程,不影响零碎可用性的依赖称作弱依赖,反之为强依赖。

强弱依赖治理

强弱依赖治理就是通过迷信的伎俩继续稳固地失去利用间依赖关系、流量、强弱等数据,提前发现因为依赖问题可能导致的故障,防止依赖故障影响用户体验,积攒数据继续推动零碎稳定性晋升。

两轮强弱依赖治理最佳实际

发现

人工梳理

在后期,咱们通过投入相当人力,通过代码走读的模式将用车外围链路上的所有依赖进行梳理。

如何鉴定强弱依赖

先确定主业务,再评定依赖的服务对主业务有没有影响
eg:对于用户扫码业务,会有很多前置校验,比方用户用车资格、车辆信息和状态查看等。

以的晚期用车零碎某服务为例(以下简称 ride):

如上图所示,通过人工梳理发现,外围业务链路只有:创立订单 / 开始订单 / 完结订单 / 查问订单等,但服务依赖却有几十个,redis 实例、数据库、mq 等资源依赖也很多,究其原因,是因为 ride 服务一共提供了几十个接口,除了后面说到的 4、5 个接口是外围接口外,其余均为非核心接口,还有很多后置解决的业务逻辑,导致 ride 服务依赖很多外围流程不相干的弱依赖服务和资源,大大影响了服务的稳定性。

故障演练

前期,尤其故障演练在两轮的逐步落地

咱们通过服务配置文件整顿服务依赖,而后通过故障演练,在线下一一对依赖注入异样,验证主业务是否可用。从而甄别强弱依赖。

目前咱们正在使用故障演练,通过给两轮非 S1 外围服务注入异样,来辨认外围链路的强弱依赖,避免外围链路上前、后端的劣化。这个点会在后续的文章《稳定性建设系列文章 — 两轮故障演练最佳实际》具体开展,敬请期待。

革新 & 预案

前、后端容错革新

针对对外围业务有影响的场景和 case,推动前后端去做容错革新。

1. 前端:将非核心流程后端接口依赖解耦,异常情况下不阻塞外围流程

以确认开锁页为例,在确认开锁页,会去拉取各种区域需收取的调度费规定,以及骑行费用计价规定,最初会加载“确认开锁”按钮。

如果此页面对拉取这些计费规定的接口是强依赖,例如当后端聚合这些信息的接口呈现故障时,将导致“确认开锁”按钮加载失败,业务流程无奈推动,重大影响用户用车。

如果此页面对拉取这些计费规定的接口是弱依赖,例如当后端聚合这些信息的接口呈现故障时,会导致局部计价规定信息内容加载不全,但外围业务流程仍可持续推动,用户体验并未受到太多影响。

故,前端须要将此类后端调用做好容错,进行解耦,将其变成弱依赖,使外围业务流程仍可持续推动。

2. 后端:对弱依赖的异样做正当的捕捉逻辑,配置正当的超时、熔断以及限流

设置正当的超时

从用户体验和零碎稳定性角度登程,无关网络调用的申请,都须要配置超时。在服务端设置超时时,须要思考到业务自身的执行耗时,加上序列化和网络通讯的工夫。个别可依照接口 RT 的 95 或 99 线来设置超工夫。当然客户端也能够依据本人的业务场景配置超时工夫,例如一些前端利用,须要用户疾速看到后果,能够把超时工夫设置小一些。

设置熔断

某个服务故障或者异样时,如果该服务触发熔断,能够避免其余调用方始终期待超时或者故障,从而避免雪崩,只有是弱依赖服务,并且能设计正当的获取返回值的计划(返回值能够是默认值,或者通过一种后备(Fallback)计划获取的值),个别业务场景都能够做熔断解决。比方服务异样时咱们能够熔断后走默认逻辑,让通过校验,既使外围业务流程仍可持续推动,也使得服务拜访变低,给予了零碎复原的窗口。

设置限流

底层外围服务接口,以及外围对外的接口肯定要做好限流,保障业务零碎不会被大量突发申请击垮,进步零碎稳定性。

外围与非核心业务隔离

线程级隔离

通过信号量或者线程池等技术实现线程隔离

过程级隔离

1. 业务拆分

将非核心业务与外围业务进行服务拆分

2. 分组部署

进行分组部署,让上游调外围和非核心调用拜访不同的分组

上面以 ride 服务的治理为例,来阐明在过后上线工夫紧迫、稳定性要求高的背景下外围与非核心业务隔离这三种形式应如何做取舍。

首先,因为 rpc 申请调用的线程是由 soa 框架创立的,所以通过信号量或者线程池等技术实现线程隔离不可行;而后对于分组部署,因为过后的 ride 服务有多畛域的业务逻辑,尽管分组部署可能解决运行时业务流量隔离的问题,然而没法防止因代码变更、公布引起的零碎不稳定性。所以,咱们最初抉择了进行业务拆分,并且因为咱们曾经可能明确外围业务的范畴以及外围业务上下游的依赖,影响范畴可控,故最终咱们决定将外围业务从服务中拆出,而不是将非核心业务拆出。如下图:

人工降级开关

针对具体的业务场景,以场景为最小单位,编写资损可控的业务兜底,配置相应的动静切换开关,异样产生时,可一键切换至兜底逻辑。

3. 验证
咱们通过服务配置文件服务依赖,而后通过故障演练,在线下一一对依赖注入异样,验证主业务是否可用。从而甄别和验证强弱依赖。

现状 & 问题

比拟多关注服务与服务之间的依赖关系,疏忽了对中间件 (redis/hbase/mq 等) 的依赖。
比拟多关注运行时阶段,疏忽了对于启动阶段和进行阶段的治理。

(本文作者:周铭敏)

本文系哈啰技术团队出品,未经许可,不得进行商业性转载或者应用。非商业目标转载或应用本文内容,敬请注明“内容转载自哈啰技术团队”。

正文完
 0