导读
2018年十一当天,高德DAU突破一个亿,不断增长的日活带来喜悦的同时,也给支撑高德业务的技术人带来了挑战。如何保障系统的稳定性,如何保证系统能持续的为用户提供可靠的服务?是所有高德技术人面临的问题,也是需要大家一起解决的问题。
高德业务规模
支撑一亿DAU的高德服务是什么体量?可能每个人的答案都不相同,这里从基础设施的角度给大家做个简单的介绍,我们有数千个线上应用,分别部署在全国各地多个机房中的数万台机器上。
这张图是高德业务核心链路的架构,从图中可以看出高德业务具有相当高的复杂性。当然,真实系统远远要比图表示的复杂,如果用这张图来代表高德整体业务形态,无异于管中窥豹,太过于片面。
对于如此大规模,高复杂度的系统,如何保障系统的稳定性,是高德技术人长期面临和解决的问题。
保障稳定性的手段
如何保障系统稳定性是几乎所有互联网企业都需要面对的问题。通常来讲,有五种手段来从理论上保障系统的稳定性,分别是:
- 容量规划:根据以往业务的流量,估算出未来(通常是即将来临的大促,节假日)的流量。以整体流量为基础,估算出每个子系统需要满足的容量大小。然后根据子系统的容量来计算出需要的资源数量,对系统进行适当的扩容。计算方式可以简单的表示为如下公式:
<p style="text-align:center">机器数量 = 预估容量 / 单机能力 + Buffer (一定数量的冗余)</p>
- 流量控制:系统需要防止流量超过设计的容量,对超出设计的流量进行限流。各业务也需要对超出子系统服务能力的流量进行限流,对超负荷的服务进行降级。
- 灾备:一旦系统发生灾难性故障,需要将流量切换到容灾机房,避免对大量用户造成损失。
- 监控:对服务进行全方面的监控,实时掌控系统的状态,对系统中出现的问题及时预警,做到早发现,早治理。
- 预案演练:对系统可能面临的问题要进行全面的预演,结合断网,断电等等灾难模拟的手段来检验系统在灾难面前的表现。
有了稳定性保障的五大法宝,我们是否就可以高枕无忧了呢?答案是令人遗憾的,这里有两个残酷的现实例子,告诫我们不要太乐观。
多年前的某年春节前夕,我们对高德核心链路进行了压测,压测设计的流量要高于预估的春节流量,系统在当时表现良好,各项指标都满足要求。可是春节期间,服务因某种原因发出告警,而此刻线上流量的水位并没有超过我们的预期。
还有一次在某年五一期间,该服务再次发出预警,而且和春节的那次预警的原因不一样。
我们的稳定性保障手段是基于对于系统的认知来实现的,而认知往往是真实世界在头脑中的映射,是一种模型,或是真实系统的快照。系统的真实状态往往和我们观测到的不太一致,基于观测到的模型对系统进行的测量也往往会不够准确,对于系统,我们要保持敬畏。对系统进行不厌其烦的模拟,无限的接近真实系统的状态,是永恒不变的追求。
上述稳定性保障的工作,只能在理论上保证系统的抗压能力,但是不能确定在真实流量到来的时候,系统的表现如何!
因此,我们需要演习,需要让真实的流量提前到来!
全链路压测
如何让真实的流量提前到来?我们需要借助全链路压测,那么什么是全链路压测呢?
我的理解是:把全链路压测拆分为两个部分来看。一是全链路,一是压测,分别来理解:
- 全链路:分为两层意思;一是自顶向下,一个请求在系统中经过的完整路径。二是一系列动作的集合,比如从用户登录,到浏览商品,到选择商品,到加入购物车,到支付等等这整个环节。对于高德业务而言,我们关注的是第一种全链路。
- 压测:通过对海量用户行为模拟的方式,对系统逐步施压,用于检验系统的稳定性。
集团的战友们把全链路压测比作 "终极武器",非常的形象。既然是 "终极武器",那就需要有足够的威慑力,对于高德来说,目标是:提供真实的流量,在真实的环境中来检验系统的稳定性。
这里面包含三个关键点:
- 真实的流量:流量的量级和特征贴近真实的世界。
- 真实的环境:直接在线上环境进行。
- 提前进行:在流量洪峰到来之前。
做到这三点,才能称得上是一次真正意义上的演习,才可以叫做全链路压测。
高德全链路压测面临的挑战
高德全链路压测面临众多方面的挑战,除了分布式系统固有的挑战外,高德全链路压测还面临着业务特殊性的挑战。
分布式系统的特性
- 不确定性
我们认为的流量有序的,而真实的流量却是随机的,不确定的。
- 抖动性
在理论的世界里面,吞吐量是请求量的函数,可以表示为如下的公式:
<p style="text-align:center">Throughput=f(load)</p>
如果没有其他因子的干扰,在系统达到饱和之前,吞吐量和请求量的关系应该是线性的。而现实世界里面,这种理论模型几乎是不可能出现的。为什么?因为抖动。为什么会出现抖动?因为网络,磁盘等等的不确定性。
- 排队系统的特性
我们的业务可以简单的抽象成为一个排队系统,请求从左边随机的进入系统,等待被处理,处理完成之后,从右边离开队列。在系统未达到饱和状态时,系统可以很好的处理用户的请求,而一旦队列接近饱和,那么队列的长度可能会显著的增加,而且请求的平均响应时间也会出现增加,甚至会出现部分请求超时的情况。对于一个理论上能处理 1000q/s的系统,在不同流量的情况下,可能的状态如下(特定系统的测量结果):
从图中可以看出:
- 请求达到率增加2倍,队列的长度会增加约60倍。
- 当系统接近饱和时,请求端极小的变化将会对系统造成很大的影响。请求达到率从0.95 ~ 0.99,队列的长度将增加40%。
排队系统的特征是:系统会在接近饱和时出现拥堵,拥堵会导致服务的时间变长,而这反过来又会加重拥堵的程度。随着情况的恶化,系统的资源(cpu,mem)最终会被耗尽。拥堵和服务质量下降表现为正相关性,这种特性会随着时间急剧的恶化,最终拖垮系统,出现故障。
高德业务特点
出行业务有其特有的特殊性,会受到诸多因素的影响。具体到高德业务而言,系统的行为会受到区域,地形,路况,路网密度,季节,天气,政府活动等等因素的影响。
以驾车导航为例,导航系统会受到如下因素的影响:
- 区域:不同的区域经济发展水平不一致,人们选择出行的交通工具也会不一样,经济发达地区的人们汽车拥有率会更高,使用汽车出行的频率也会更高。
- 地形:山区,城市繁华地区会因gps信号遮挡导致定位不准确,可能被系统认为偏航,从而引发路径重新规划。
- 路况:事故,拥堵,施工,限行,管制 这些路况都对导航服务造成影响。
- 路网密度:导航算法所要求的计算资源和路网的密度有很强的关联,路网越密,路径规划所消耗的cpu资源,内存资源就会越大,同时计算的时间也会越长。
- 距离:路径规划的距离越长,导航算法对计算资源的要求就越高。
- 季节&天气:人们的出行行为和季节也会呈现相关性,如 五一,端午 人们可能集中前往景区旅游。十一,春节 人们可能会集中返乡。这样在导航行为上就会出现导航距离分布不同的情况,不同的导航距离对服务的要求会不一样,越长距离的导航对服务资源的要求越高。
- 政府活动:交通管制,修路,限行等等。
对于高德而言不能单纯的通过放大流量来对系统进行压测,在流量构造阶段我们需要考虑到流量的特征,考虑到所有影响服务行为的因素。
高德全链路压测平台的自建起因
身在阿里,说起全链路压测,首先想到的肯定是大名鼎鼎的Amazon平台,Amazon 诞生于2013年,自2013年起,Amazon一直作为淘宝、天猫稳定性保障体系中神一般的存在。经过多年的发展和演进,Amazon平台已经日臻稳定和成熟,在施压能力,链路治理,数据构造,用户模拟方面已经做到极致。
所以,在落地高德全链路压测的时候,首先考虑的就是借助Amazon平台。经过充分的调研和部分项目的试用,我们发现Amazon平台并不能满足我们的要求。
Amazon平台诞生于淘宝,作为淘宝,天猫稳定性保障体系中重要的成员。Amazon 追求的是超高的施压能力和极强的平台稳定性。另外,淘宝的双11,双12全链路压测是多团队合作的项目,一次全链路压测可能需要数百人的参与,对于这种超大规模的全链路压测项目,成败的关键在于团队的合作。平台需要搞定的是人无法搞定的事情,对于Amazon来讲,要做的就是把事情做到极致。
高德的全链路压测流量的要求远远不及淘宝的全链路压测,并且通常全链路压测的周期都不会太长(通常在2周左右,这个时间还需要缩减),所以我们比较关注压测成本的问题,例如压测数据的构造成本,压测资源申请的成本,错误排查成本,以及便捷性方面的问题,例如压测过程的可视化,压测报告等。
另外,高德的日常环境的压测需求比较旺盛,除了全链路压测外,我们还需要借助别的平台(如PAP,PAS)来满足日常的压测需求。
从成本收益的角度出发,最终我们选择自研压测平台来满足高德的全链路压测需求,以及日常的压测需求。
高德压测平台的自建思路
如何打造一款全新的压测平台?
回答这个问题,先要回答平台的目的是什么。高德压测平台的目的是什么?一定是为了解决业务的问题!结合上文对全链路压测的描述,对高德业务特点的描述,我们建设压测平台就需要回答这几个问题:
- 如何保证场景的真实性?
- 线上压测,如何保证压测流量不影响线上用户,如果保证压测数据不污染线上数据?
- 如何构建超高流量?
- 如何降低使用成本?
- 如何降低资源成本?
如何保证场景的真实性
压测要保证真实,需要在压测场景上做到全覆盖,需要从协议支持和用户行为两个方面来满足场景的真实性。
- 协议支持:
对于高德服务而言,不同的用户场景使用到的通信协议不一样,例如PC端主要是http协议,而移动端则是accs协议。因此全链路压测的场景设计上首先需要满足对全协议的支持。
- 用户行为:
除协议外,场景构造还需要考虑到真实场景的用户行为,目前的做法是使用线上日志作为原材料,对日志进行过滤,整理,最终形成标准化语料文件,这样可以在一定程度上保证压测数据的真实性。这种低成本的做法,只能借助业务同学的经验去保证。人总会出错,因此未来在场景真实性保障方面不能仅仅依靠人的经验,平台需要通过技术的手段,通过模型,依靠机器去保证。
线上压测,如何保证压测流量不影响线上用户,如何保证压测数据不污染线上数据?
为了保证压测流量不影响线上用户,不对污染线上环境,首先要做的是:链路上的各系统,中间件需要做到对压测流量进行识别,具体而言需要如下步骤:
- 接入鹰眼
- 使用集团的中间件(集团的中间件都支持压测流量识别)
- 业务改造(结合鹰眼对压测标进行透传,对于某些业务可能需要在业务层面对压测流量进行过滤,如对三方系统的调用需要替换成mock方式)
除此之外,还需要有完备的监控手段,在发现服务问题(如系统中发生限流,降级,RT突然增高等等)时,及时的止损。
如何构建超高流量
对线上服务的压测,需要构造出超大规模级别的压力。这需要大量的施压机器共同努力才能达到。要达到验证服务稳定性的目标,全链路压测就需要具备构造超大规模压力的能力。我们目前的策略是自建分布式Jmeter施压集群,依托于Aone的快速部署和便捷的扩容能力来迅速的满足压测流量的需求。
如何降低使用成本
- 压测引擎:以往高德线下的压测属于工具形式,大家使用Jmeter对被测服务进行压力测试,负责压测的同学都对Jmeter比较熟悉。考虑到平台使用的成本,和工具转平台的便捷性,我们使用Jmeter作为TestPG的压测引擎。
- 快速压测:高德有非常多的单链路压测需求,而且服务的接口数量比较少,也比较简单。对于此类型的压测需求,平台需要提供开速开始的能力,简化语料->场景->任务的标准化流程。
- 压测数据管理:全链路压测使用的压测数据(语料文件)的大小达到数十G,文件的存储和分发对系统的设计而言都是不小的挑战。目前采取的做法是使用OSS来存储压测数据,通过一定的策略和算法在施压机器上对语料进行预加载。
如何降低资源成本
高德每年会进行两次大型的压测(春节和十一),其他时间如:清明,五一,端午视各业务线的情况而定。在大型压测时,需要大量的压测资源(几百台,4C16G),而平时少量的压测资源(几十台)就足以满足日常的压测需求,因此在压测资源的管理上要保证灵活,需要时快速满足,不需要时释放,避免资源浪费。
目前TesgPG提供两种施压集群扩容的方式:一是使用Aone部署,通过Normandy平台进行快速扩容(pouch);二是支持用户自主提供压测机,技术方案是使用Docker + StarAgent 方式来实现施压机的自动部署。
压测资源调度:除了支持全链路压测外,还需要支持日常的压测。对于不同的压测,系统在设计上要满足多租户,多任务的需求,在压测资源的管理方面做到按需分配(目前是人工评估)。
高德压测平台的自建目标
- 短期目标:
支撑高德全链路压测。
为高德所有服务提供线下压测的能力。
- 中期目标:
成为高德线上系统稳定性的试金石。
- 长期目标:
产品化,服务于集团的更多业务。
高德压测平台架构与特点
高德压测平台架构
- 高德压测平台业务架构
- 高德压测平台技术架构
高德压测平台特点
- 极速压测:
对于大部分简单压测需求,TestPG提供极速压测的能力,只需要填写被测服务地址,设定压测必须的url,请求类型,请求字段,QPS,压测时长等信息,就可以开始压测。对于初次使用平台的用户,平均15分钟即能上手压测。
- 调试能力:
TestPG平台提供两种调试手段:挡板调试和服务调试。
- 挡板调试:请求不会发往真实的服务,施压机作为调试挡板,对语料格式,url格式,请求参数进行校验。
- 服务调试:平台将压测请求(默认20条请求)发往真实的被测服务,并详细记录请求的上行数据和下行数据,格式化后,通过平台展示给用户。
调试的目的式帮助用户调整压测的参数,为正式的压测做好准备。
- 错误定位辅助:
TestPG平台会详细记录压测过程中出现异常的请求,对请求的上行数据和下行数据进行格式化保存,用户可以在压测过程中通过平台查看异常日志,定位错误原因。
- 详细的压测报告&基线对比:
TestPG平台在压测完成后自动产出压测报告,压测报告详细包括本次压测的整体、各场景、所有接口的QPS,RT,最大、最小RT,百分统计RT,错误请求数量,错误请求率。并且还包含压测时的实时QPS ,RT图表,以及被测服务的基础监控数据。
此外,压测报告还支持基线对别,若设定了基线报告,后续产出的压测报告都会和基线进行对比,在报告中就会体现出服务性能的变化。压测报告的详细信息可以查看下文平台展示中压测报告部分。
高德压测平台展示
压测看板
调试
错误排查
压测报告
高德全链路压测的实践
2018年十一是我参加了高德全链路压测,当时团队的同学一起聚在稳定性保障会议室里,对高德的核心链路进行了为期两周的全链路压测。
高德的全链路压测流程是比较传统的方式,下图是历年全链路压测的大致流程:
高德压测平台的现状
高德压测平台从2018年开始启动,经过大半年的发展,已经成功支持了高德2019年春节全链路压测,2019年五一全链路压测,在施压能力方面达到百万级别。
目前高德压测平台包括语料生产,场景构造,压测资源管理,压测任务调度,压测过程监控,压测调试,压测错误排查,压测报告生成,压测报告评估(对比基线,从QPS,rt,cpu,mem这几个维度进行压测结论的评估)等功能。
平台从2018年底投入使用至今,共执行几千次的压测。通过开放api的方式,平台开放压测能力,现已成功和持续交付平台打通,为持续交付提供可靠的性能指标。
自春节后,平台主要致力于降低压测门槛,提升压测效率。对于大部分简单的压测需求,从原有的语料->场景->任务逐级构造模式简化为一键压测模式,在初次使用平台成本方面,简单的压测工作预计能从平均3小时,减小为平均30分钟。
虽然高德压测平台在近一年的时间里,取得了一些成果,我们也支撑了几次全链路压测。但是我们的全链路压测还不能完全满足上文的三个要求,其中最关键的场景真实性还无法得到保证,"全链路压测" 对于高德来说,还是远方,我们还有很多路要走,还有很多困难要克服。
高德压测平台的未来
在可见未来里,我们期望在以下几个方面去探索和实践:
全链路监控
TestPG目前的监控是基于用户自定义链路的监控,在链路真实性上无法得到保障。未来我们将会与运维团队合作,打造基于EagleEye链路自动梳理的全链路监控。除了基本的系统指标监控功能外,TestPG平台还会在下面的几个方面进行探索:
- 监控大盘,全面的展示系统的状态
- 短板机器,短板服务的识别
- 基于时间序列的性能问题挖掘
- 结合邮件,钉钉等手段,对发现的问题进行及时的报警
简化语料生成流程
目前压测语料的生成采用的是用户自定义脚本的方式。平台定义好语料目录格式,语料文件格式,用户编写语料处理(一般以日志文件为基础)的程序,然后上传到平台。平台会执行用户提供的程序,然后在将程序的输出文件存储在OSS上,以备压测之用。
这种方式降低了平台的实现成本,也给用户提供了足够灵活度,但是增加了语料的处理门槛。未来我们会将这部分工作全部交由平台来处理,用户只需要提供原材料,配置生成规则即可。
丰富压力模型
TestPG平台目前的压力模型是Jmeter原生的,为了最大限度的接近真实场景,在压力模拟上,我们还需要具备如下几种压力模型:
- 步进施压
- 抖动施压
- 脉冲施压
压测置信度评估
压测场景能否代表真实的用户场景?这是一个TestPG目前还无法回答的问题。场景的真实性现在依托于业务同学的经验,业务同学按照自己抽象出来的业务模型对原材料(通常是线上日志)进行处理,生成平台规定格式的预料文件。语料对平台和用户来讲,都是黑盒子,除了被测系统外,没人知道语料的模型是否接近真实世界的用户场景。
因此,我们期望通过一些技术手段来对压测场景的真实性进行一个科学的评估,这便是压测置信度评估。置信度评估的目标是评估压测的场景和我们期望的场景相似度,下面是压测置信度评估需要探索的方向:
- 建设场景特征库(例如五一,十一,春节)
- 基于特征库的压测场景置信度评估
- 基于地理位置的压测场景置信度评估
- 基于链路覆盖度的压测场景置信度评估
- 基于流量模型的压测场景置信度评估
结合上述维度的评估数据,我们可以给出一个具有价值的评估报告,作为一个重要的参考,可以帮助用户评估压测的效度。
链路改造
TestPG平台的中期目标是要支撑高德业务的全链路压测,成为高德系统稳定性的试金石。但现在我们离真正的全链路压测的距离还很远,我们的压测场景只覆盖了读请求,还不具备支持写请求压测的能力,原因是系统还不具备全链路流量识别的能力,还不具备隔离压测流量的能力。未来,全链路压测,全场景覆盖是必经之路。
关注高德技术,找到更多出行技术领域专业内容
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。