写点什么

当流量突变时,系统中的负载保护如何应对?

  • 2020-05-20
  • 本文字数:4617 字

    阅读完需:约 15 分钟

当流量突变时,系统中的负载保护如何应对?

有人说:“击垮一家互联网公司的最快方式不是运营疯狂烧钱、不是产品经理胡乱决策,而是系统核心功能的持续不可用。”的确,我们常会见到一次大规模宕机导致企业损失上千万,甚至市值大量蒸发。由此可见,系统稳定性和高可用的重要性。


在企业业务系统中,技术选型多种多样,系统的性能和健壮性参差不齐,业务流量变化无常,如何才能保证各种业务流量安全运营,系统在任何情况下都不会崩溃呢?InfoQ 采访了 QCon 全球软件开发大会(北京站)2020 的讲师朱龙云,他和我们分享了关于系统负载保护的设计原则,以及发生流量突变时的具体应对措施。

负载保护的总体原则

虽然业务系统在正常情况通常是感知不到负载保护的存在,但是负载保护却是所有系统都必须具备的能力,它可以防止系统“崩溃”。那么,常见系统的负载保护在设计之初一般都遵循什么样的设计原则呢?


朱龙云表示:虽然各个系统的负载保护设计都会有自身的特点,但从设计角度从下到上基本可分四层:


  • 通用层:这一层是系统通常都需要的基础属性。例如:易部署、高度可观察,具备容灾和扩缩容能力,隔离失败 (服务 / 模块)

  • 机制层:这一层包含了与负载保护密切相关的基础属性,在负载保护系统演化中相对策略层变化是慢的。例如低消耗、低耦合,容错性、健壮性、适应性、伸缩性和异构性。

  • 策略层:这一层是负载保护的策略算法,是在系统外侧最容易被看到的,容易引起广泛的讨论。我们常讲到的限流、降级和熔断算法就在这一层。

  • 系统层:这一层主要是根据负载保护运营反馈,找出系统整体设计的缺陷和不足,并进行相应调整,并将系统设计与自动扩容融合。


如果具体到负载策略的设计原则,一般需要考虑到调用链、业务与资源、整体与局部、扩展性等等。


  • 调用链:在这一维度,我们需要管控好上游入口的流量,实时计算自身服务资源消耗,并实时评估下游服务服务质量,确保整个调用链整体流量安全。

  • 业务与资源:通常,业务流量会有时间错峰,我们可以将错峰业务部署在一起,提高机器资源利用率。但这样可能会导致业务之间相互影响,负载保护就在此时发挥作用,当业务负载超过自身预分配资源时,继续使用系统尚未被其他业务消耗的资源。当各个业务总体消耗资源超过系统整个负载安全上限,按一定策略对相应业务进行限制;

  • 整体与局部:达到整体效果的负载保护需要“均匀”分配到各个最小计算单元,但这里的“均匀”不是绝对数量的“均匀”,而是与每个计算单元相匹配的“均匀”,即与系统的负载均衡相匹配;

  • 扩展性:业务对负载保护会有扩展性的需求,例如按照业务重要程度、用户分布或者资源消耗等进行个性化限流以及降级服务。

整体系统和单个服务的负载如何平衡?

系统的负载保护既包括单个服务的负载保护,也包括整体系统的负载保护,前文我们也讲到了整体与局部负载保护的设计原则的关键词是“均匀”,如何实现“均匀”呢?


我们可以分两个部分来讨论:


第一部分是整体系统与调用 topo 中某个节点关系。我们需要先了解系统中的负载脆弱点以及原因。


负载脆弱点可能是技术引起的,例如动态语言实现服务,性能就会差一些;可能是资源引起的,例如部署的物理资源较少;可能是业务引起的,例如计算密集或者外部依赖的问题。然后,我们需要针对脆弱点做好流量管理,自身负载的实时监测,对脆弱点上游做好熔断机制,并做好监测预警,防止该点引起系统整体雪崩。同时从长远角度考虑,还要尽可能优化或者消除因设计引起的系统脆弱点。


第二部分是单点服务集群与计算单元的关系。


集群中各个计算单元需要负载均衡,而通常情况下,各个计算单元是异构的,这就需要匹配相应的计算资源能力。负载保护需要保证当系统过载时,负载依旧是均衡的,避免出现有的计算单元过载,有的计算单元还有资源剩余。


总之,负载保护的策略具体实现都需落实到单个计算资源,同时各个计算资源的信息需要上报汇总起来做整体决策。

上游模块与下游服务的负载保护

除了整体系统与单个服务,我们还常会遇到上游模块与下游服务之间的负载保护。朱龙云表示:“上下游之间的负载保护最重要的是做到相互信任不依赖,对方通知异常,能根据通知信息采取措施。对方不通知也能及时发现异常,采取措施,不会因为自身原因造成系统雪崩。”


展开来讲就是上游需要为下游做好流量保护,但是下游不依赖这种保护。当上游没有保护好,系统流量过载,下游能触发自身的负载保护,当上游故障,流量突然下降,下游也能发现。如果下游服务异常,不能提供正常服务,下游需主动通知上游。如果没有通知,上游也需要能自身发现异常,并采取措施。而当下游服务正常时,上游也要及时探测到,并开放对外服务。

如何评判负载保护的效果

一个系统的负载保护设计好了之后,如何评估设计得是否合理呢?一般来说,我们会通过以下指标来判断:


  • 低能耗:负载保护本身不能挤占太多的系统资源;

  • 适应性:负载保护本身对流量变化不敏感,不会因为业务流量变化而频繁扩缩容;

  • 容灾能力:负载保护的作用是帮助业务尽快恢复,所以自己不能成为瓶颈,自身故障不能影响到整个业务系统;

  • 透明扩缩容:业务系统扩缩容时,应该感觉不到负载保护的存在;

  • 健壮性:保护机制触发时机既不能过于敏感,造成系统颠簸,同时也不能迟钝。


一个真实存在的系统往往都是有自身服务的职责和边界,因此一个合格的负载保护系统也要协助系统在各种场景下对外提供服务。


  1. 在一定负载范围内,系统在不触发负载保护的情况下,对外提供高可用服务;

  2. 系统对外提供有损服务,这种场景已经触发负载保护;

  3. 系统只保证自己正常运行,不再保证对外服务的数量,排除异常之后,系统可以立刻对外提供高可用服务,这种场景需要负载保护深度接入;

  4. 系统不对外服务,异常排除之后,结合线下处理,系统在可预测、可控时间范围内恢复对外服务。

流量突变时,负载保护如何应对?

当流量发生突变,系统中的负载保护应该采取什么样的措施呢?

负载过高

当系统负载过高时,通常会采用三种措施来保护系统,限流、降级和熔断。


限流一般是指限制入口流量,触发机制可以是提前预设阈值、下游通知或者自发检测到资源过载,而具体策略可以是刚性,也可以是弹性。一般来说,刚性是指超过一定量之后,就全部不再提供服务,而弹性就会涉及降级。


降级一般是指限制业务或用户。如果是读写分离的业务,通常读的量比较大,写的量比较小,而且敏感,所以当系统过载时,就会限制读的量,而写的量不会直接限制。读少了,同时会自动引起写减少。这种方式即使是触发了负载保护,也会使系统尽可能有好的体验。限制用户指的是按照一定策略使得部分用户无法访问该服务。


熔断主要是发现自身或者下游不能正常服务,主动不再对上游提供服务。但是熔断也可以引入降级服务策略,允许部分服务正常运行。


总体来看,限流偏向于管理入口流量,熔断偏向于保护下游服务。降级是为了在系统触发负载保护时,尽可能提供弹性服务。一般来说,熔断比限流严重,而限流比降级严重。

负载过低

与负载过高相比,大家对于负载过低的关注度会比较低,但其实负载过低有时也会带来严重后果。


一般来说,出现负载过低的情况有以下几种:


第一种是比较直接的,业务量太少,这种情况的解决方法就是与其它业务混合部署,再采用负载保护;


第二种是关键业务或节点进行了独立部分,这种情况一般是企业根据业务情况做出的运营策略,不需要调整;


第三种是服务实现的缺陷,例如服务里面存在 idle 操作,造成机器资源利用率不高;


第四种是服务设计的缺陷,例如 QPS 达到一定阈值,服务器性能就会断崖式下降,造成机器资源利用率不高。

负载均衡

负载过高或过低都不可行,我们需要做到负载均衡。首先,调用链节点之间的负载要均衡,没有明显瓶颈,否则容易触发负载保护;其次,单个服务集群的各个服务器之间的负载要均衡,包括硬件和软件的负载均衡。


如何实现负载均衡呢?朱龙云认为主要考虑以下几个方面:


  1. 系统的冷启动策略,可以从一个预设的平衡条件开始逐步调整;

  2. 系统性能指标,例如响应时间,错误码等;

  3. 负载调度策略,基于机器的服务能力来分配,例如服务的平均响应时间、成功比例以及内部队列长度等;

  4. 负载均衡的精度和稳定性,精度高的好处是能够区分出异构机器的服务能力,而坏处在于频繁调整各个机器服务权重,有可能引起系统颠簸;

  5. 负载均衡接入方式,常见的有网关接入和 Agent 接入;

  6. 即使触发了负载保护依然需要负载均衡,不然就有可能造成系统服务能力浪费。

企业中的负载保护存在哪些问题?

在企业中,我们经常会遇到这三种负载保护的情况:第一种是企业在系统设计之初就考虑负载保护,系统上线之后没有出现大故障,负载保护不断优化、完善,并与业务逻辑进一步融合;第二种是在系统运营过程中遇到了负载保护的问题,并得到了比较好的解决;第三种是遇到了负载保护问题,不能彻底解决,负载保护系统部分可用,需要堆人力来运营系统。


第一种情况是最理想的,但是现实中很少见,因为这其中不只涉及到技术问题,同时也需要考虑项目进度、成本等多种因素。而其它两种情况都是企业实践中比较常见,当系统平稳运营时,资源利用率的情况也比较好,一旦发生外部流量陡增或者是关键路径触发异常等情况,各个服务之间的连锁反应可能会使整个系统崩溃,短时间内无法恢复,同时共享资源的业务也会受到影响。


在单体架构阶段,负载保护会比较简单,系统崩溃了也较容易恢复。而在微服务阶场景下,负载保护就复杂了,由于调用关系复杂,系统因过载崩溃了,需要先找到引起奔溃的节点,有时可能是几个节点连环触发的,系统无法通过简单扩容恢复。


所以,我们需要在系统设计之初就考虑到负载平衡,同时做好以下工作:


  • 检查现有系统是否存在明显短板,容易触发过载;

  • 系统与外部系统之间要做好入口流量控制;

  • 系统内“玻璃体质”服务的模块调用方要有错误抑制、熔断、降级等机制;

  • 关键服务的负载要实时监测、评估,并适当提高冗余资源;

  • 负载保护要与监控紧密结合,尽早发现系统异常,及时触发自动扩容;

  • 负载保护触发时要采访业务侧提供的策略;

  • 根据系统运营结果,及时发现系统在设计和运营方面的不足。


在流量管理方面,业界还出现了一个新的“风向标”——Istio,其理念是将业务中的很多微服务治理功能下沉到基础设施。这个设计理念是相当有创造力的,其实从软件架构设计的角度来看,这些思想方法并不独特,我们或多或少都曾应用过,例如集群入口流量管理与 Istio 南北向通信,集群内弹性熔断与 Istio 东西向通信,集群内脆弱服务的保护与 Istio 的智能代理,流控实现中数据和控制分离与 Istio 中数据平面和控制平面分离。但需要注意的是,再安全健壮的基础设施也挡不住业务“自杀式”设计,业务只有科学合理设计,才能与基础设施相得益彰,一起发挥整体效能。


嘉宾介绍


朱龙云,腾讯科技增值服务部互娱 AMS 监控系统负责人。2007 年加入腾讯,曾负责腾讯网网站广告发布系统,从事 CPD/CPC/CPM 等形式广告发布和运营,在广告 / 监控 / 流控等领域拥有多项专利。现就职于腾讯游戏增值服务部,曾参与开发过 Pandora 手游营销系统,支持手游时代新营销形式;主持设计和实现 AMS 系统全局负载保护系统,保证微服务系统在流量突变时安全运。当前主要负责 AMS 游戏营销监控系统,从事现网故障分析、弱阈值设置监控、主动探测系统和异常检测等方面工作。对分布式计算,大数据和函数式编程等领域比较感兴趣。


QCon北京2020的演讲中,你将从朱龙云老师的分享中了解到:微服务环境上游流控/本机负载保护/下游熔断方案相结合的整体系统负载保护方案;微服务环境下监控设计的方案,与传统监控差异,以及未来可能的发展方向。点击了解详情


2020-05-20 11:457157
用户头像

发布了 497 篇内容, 共 327.4 次阅读, 收获喜欢 1923 次。

关注

评论

发布
暂无评论
发现更多内容

算法喜刷刷之验证二叉树的前序序列化

Kylin

算法 3月日更 刷题笔记

3月12日学习笔记

Nydia

翻译:《实用的Python编程》05_01_Dicts_revisited

codists

Python

真·“拜师学艺”?2021中科院开源之夏,开源大牛1V1&万元奖金只等你来!

京东科技开发者

开源 开源社区

硬核!一文学完Flink流计算常用算子(Flink算子大全)

五分钟学大数据

大数据 flink 28天写作 3月日更

带你了解VXLAN网络中报文的转发机制

华为云开发者联盟

网络 网关 VXLAN 报文 分布式网关

“新作者 新入驻 新征程”第一季获奖名单

InfoQ写作社区官方

热门活动

一步一步教你如何在Centos7中配置Kafka运行时环境

happlyfox

28天写作 3月日更

华云大咖说 | 华云数据与瀚高软件携手共建国产云生态 助力政企用户安全可靠发展

华云数据

算法攻关 - 验证二叉搜索树 (O(n))_098

小诚信驿站

刘晓成 小诚信驿站 28天写作 算法攻关 验证二叉搜索树

(28DW-S8-Day20) 以太坊账户

mtfelix

28天写作

《精通比特币》学习笔记(第八章)

棉花糖

区块链 学习 3月日更

滚雪球学 Python 之闭包操作,本系列第 8 篇文章

梦想橡皮擦

28天写作 3月日更

ECMAScript 2016(ES7)新特性简介

程序那些事

JavaScript ecmascript ES6 程序那些事 es7

力扣(LeetCode)刷题,简单题(第27期)

不脱发的程序猿

面试 LeetCode 28天写作 算法面经 3月日更

物联网常用协议:MQTT、CoAP、LwM2M、HTTP、LoRaWAN和NB-IoT

不脱发的程序猿

物联网 通信协议 28天写作 3月日更 物联网常用协议

你以为在做的是微服务?不!你只是做了个比单体还糟糕的分布式单体!

程序猿DD

微服务

【LeetCode】验证二叉树的前序序列化Java题解

Albert

算法 LeetCode 28天写作 3月日更

翻译:《实用的Python编程》05_00_Overview

codists

Python With 关键字和语句

HoneyMoose

微服务简介

insight

微服务 3月日更

植树节,种个二叉树吧?

悟空聊架构

数据结构 算法 二叉树

《未来世界的幸存者》读书笔记

SilentMacUser

极客时间 互联网 技术学习 阅读 阮一峰

一起来学习LiteOS中断模块的源代码

华为云开发者联盟

代码 华为云 LiteOS 中断 中断控制器

“种”下黑科技,守护每株绿,“植”了!

华为云开发者联盟

华为 AI IoT modelarts 森林

关于广东欢太科技可不可信?那是你还不了解

Geek_4a453c

企业 欢太 欢太科技

如何成为一名架构师?

xcbeyond

程序人生 方法论 架构师 成长与思考 3月日更

聊聊什么是CommonJs和Es Module及它们的区别

蛙人

大前端 js ES6

这是看脸的时代吗——晕轮效应

Justin

心理学 28天写作 游戏设计

区块链应用解决方案赋能到农产品溯源上究竟能解决什么问题?

源中瑞-龙先生

2月大事件:度目CM-Mini智能面板机全新发布,飞桨PaddleGAN“复活”李焕英

百度大脑

百度 百度大脑

当流量突变时,系统中的负载保护如何应对?_软件工程_田晓旭_InfoQ精选文章