蚂蚁金服移动端高可用技术实践
摘要:对于移动技术而言,2017年是继往开来之年。一方面是移动技术领域进入深水区,另一方面移动技术边界和内涵被不断重塑。阿里巴巴希望进一步推动移动应用研发事实标准落地,从而赋能整个行业开发者。在2017年杭州云栖大会上,蚂蚁金服高级技术专家竹光为大家分享了蚂蚁金服移动端在高可用技术方面的具体实践。
演讲嘉宾简介:竹光,蚂蚁金服高级技术专家。2015年加入支付宝,主要负责客户端的稳定性和高可用,曾多次参与双11、双12、春节红包等大促的技术保障工作,主要负责保证活动期间支付宝客户端的稳定性以及可用性。
以下内容根据演讲视频以及PPT整理而成。
本次分享的内容主要分为以下四个方面:
亿级APP在可用性方面的挑战
APP线上运维的发展和演进
移动端高可用的定义、目标、核心打法
支付宝在移动端高可用技术实践
一、亿级APP在可用性方面的挑战
可用性的概念
首先分享一下可用性的概念。简单而言,可用性就是当用户想要使用APP做一个事情,这件事情做成了就是可用,没有做成就不可用。为什么没有做成?可能的原因有很多,比如有可能使用APP的时候闪退了,或者使用支付宝付款的时候,由于后台某个环节出现错误,导致了这笔支付失败了等,这些都可能造成APP的不可用。如果各种各样不可用的情况都没有出现,那么对于客户而言就是可用的。虽然每个开发人员都希望自己开发的APP是100%可用的,但是实际上这一点是不可能的,所以开发人员真正需要做的事情就是让APP发生不可用的情况越来越少。
亿级APP的可用性挑战
目前,APP开发技术已经比较成熟了,所以很多开发人员会认为自己的APP可用性应该问题不是很大,因为APP都经历了相关的测试流程、灰度验证等保障措施。但是现在情况已经发生变化了,与以前相比,APP的用户量大了很多,很多的APP都达到了亿级用户,所以一点点可用性问题其实都可能会影响大量的用户,比如APP的闪退率上涨了千分之一,虽然这一比例并不是很大,但是对于一亿用户而言,乘上千分之一就是10万人。大家可以想象一下,如果某一天大家在使用支付宝在超市付款的时候,其中的10万人出现闪退的情况,这个影响是绝对不可以接受的。现在开发移动端APP讲究动态化,业务要求实时动态地实现线上变更,可以说今天的支付宝和昨天的支付宝相比就已经产生很大区别了。而每一次线上的变更其实都会增加线上可用性的风险,而且一天中可能会发生很多次变更,在这种情况下风险也会变得很大。尤其对于作为保障APP可用性的一线人员而言,压力也会特别大。正是因为面临这么多的问题和挑战,才需要通过移动端的高可用技术体系解决这个问题,保证线上客户端高可用性。
二、APP线上运维的发展和演进
如下图所示的是这几年来支付宝客户端在可用性运维上的发展历史,大致分为了三个阶段。随着支付宝的成长,可用性运维也一直在演进,最后演进到了移动端高可用的状态。
第一个阶段就是简单的闪退监控。绝大多数的APP也做过这个事情,就是本地收集一些闪退信息并进行上报,在APP后台对于闪退率进行监控,解决闪退比较多的问题,并在APP的下一个版本中进行相应的修改,最后使闪退率维持在某一个指标以下。但是现在来看,这个阶段距离实现高可用的要求相差很远,因为用户所遇到不可用问题中闪退只占据其中一部分,所以对可用性而言,解决了闪退问题只是改进了一点点而已,还存在着大部分的问题还没有解决。
第二个阶段,在阿里巴巴内部叫做稳定性监控体系,相比于第一个阶段而言,稳定性监控体系可以说前进了非常大的一步。首先,可以监控的问题大大丰富了,通过对多种问题的监控可以了解线上用户稳定性方面的可用情况,而不仅仅是一个用户。第二个方面,稳定性监控体系具有相当程度的诊断能力和修复能力。当发现问题的时候,可以通过诊断日志等相应的方法分析故障原因并尝试进行修复。稳定性监控体系在最初的时候效果比较不错,并且阿里巴巴内部也使用了很长的时间,但是后来问题也逐渐暴露出来。举两个例子,曾经一个版本的APP在X86一款机器上运行时出现的问题非常多,但是那个机型的用户量很小,所以问题一直都没有被发现,直到很晚的时候才通过其他方式发现了这个问题,也就是说因为只监控具体问题导致已经不能发现局部人群的问题了。第二个例子,在做像双11这样的大促值班的技术保障的时候,因为监控的问题比较多,运维人员需要通过不停地翻监控来发现问题,翻来翻去最后还是不敢确定APP的可用性到底有没有问题,有时候确实会遗漏一些问题。第三个方案就是在发现了问题之后,能否快速修复还需要碰运气,有可能很快就能够修复,也有可能修复起来不太容易,需要等到下一次发版,这就使得有些问题所影响用户数会非常多。
以上就是在2.0阶段所遇到的问题,这说明稳定性监控体系也已经不够用了,需要继续进行改进,这也是支付宝决定继续做3.0阶段的移动端高可用的动机和动力。
三、移动端高可用的定义、目标、核心打法
高可用在移动端的重新定义
高可用原本属于服务端的概念,阿里巴巴的服务端都在讲高可用。服务端的高可用重点讲的是停机时间短、服务不可用时间短。移动端的高可用从服务端借鉴过来之后进行了重新定义,因为客户端不存在停机时间概念。所以,移动端高可用的定义是指通过专门的设计,结合整套技术体系,保证用户所遇到的技术不可用总次数很低。
移动端高可用的目标
简单来说,移动端高可用的目标就是实现可用率达到99.99%,这里的可用率是支付宝自己定义的概念,指的就是用户在使用APP的时候,可用次数在使用次数当中的占比,可用率达到99.99%也就意味着用户使用1万次支付宝其中的9999次都是必须是可用的,最多只有一次不可用。为了实现这一目标,还会将任务拆解成为不同的子目标分别攻克。
移动端高可用的核心打法
其实,目标上的实现还是比较困难的,因为让可用率达到99.99%其实是一个很高的指标。而为了能够努力实现这个目标,支付宝也自创了一套核心打法,主要分为以下四个部分:
客户端可用性监控。用户遇到不可用的时候,要把造成不可用的问题收集并上报上来,并且要提供足够的诊断信息用于分析解决。
高灵敏监控报警平台。需要实现当线上的问题刚刚出现苗头的时候就立即能够发现。
快速修复能力。当发现问题之后不仅要保证能够修复,还要保证修复的速度足够快。对一些级别高的故障,支付宝要求在一个小时之内完成快速修复。
故障演练。
四、支付宝在移动端高可用技术实践
下图所示的是支付宝实现的移动端高可用技术架构图,大家可以看到支付宝移动端高可用的技术架构设计也是围绕上述的四个核心打法展开的。
客户端可用性监控
问题采集:客户端可用性监控的第一步就是问题采集,当APP发生不可用时必须能够感知和采集到问题,这是基础的基础,如果没有这个基础后续什么都不能实现。那么,怎样确保当用户出现了不可用情况时能够采集到问题?这其实是比较困难的,因为我们不能保证一定可以采集到所有类型的不可用问题,但是还是会通过多种方法尽量地实现全面覆盖。支付宝把不可用问题分为稳定性不可用和业务不可用两个方面。对于稳定性不可用而言,通过2.0阶段的逐渐摸索以及各种反馈渠道、问题搜集渠道的补充,现在已经可以把各种各样稳定性的不可用问题搜集得比较全了,比如传统的闪退、卡死等以及不容易被监控的黑屏、白屏以及非闪退类型的异常退出等。目前已经采集到了大部分的问题,当然可能还会存在遗漏,对于这些遗漏的问题,还需要通过不停地搜集并补充到这个体系中。对于业务不可用而言,在开发时会对于业务不可用问题进行埋点,只需要将业务不可用埋点纳入到系统里面来,就能够基本覆盖最重要的业务不可用问题。
统一管控:当问题采集上来之后,需要通过统一管控形成客户端可用率指标。通过这个指标可以全面地评估线上某一个人群中的可用情况,而不需要像以前那样逐一检查各个指标并在最后给一个不太准确的评估结果。通过统一管控可以设计出整体的监控和报警机制以及各种算法模型,并且其扩展性更好。
埋点上报:这一功能是非常核心的。因为后续还要利用不可用埋点做高灵敏,所以埋点的实时性、准确性、到达率的要求特别高。并且对于不可用埋点而言,当客户端已经发生了不可用时才需要进行上报,而在这个时候客户端情况很可能非常恶劣,甚至此时客户端可能已经无法启动了,即便是这样也要保证埋点能够上报。为了实现这一点,我们利用了一些小技巧,比如对于Android系统而言,支付宝通过独立的轻量级进程来单独上报埋点,即便主进程已经挂掉了,但是埋点也能够实时上报上来;对于ios系统而言,采取在线上hold住进程使其报完埋点再退出去的方式,并且后续还有补偿机制,即使出现遗漏埋点的情况也能够使其最终能够上报上来。
通过问题采集、统一管控和埋点上报,基本上可以保障当用户遇到不可用问题时可以收集问题并上报服务端,做好了第一步的基础。
高灵敏度系统模型
在问题收集到的情况下需要用高灵敏系统模型做监控和报警。其实监控和报警在2.0时代就已经存在了,比如当大盘上监控的闪退率出现异常情况时就会进行报警。但是高灵敏系统模型要做的是在线上问题刚刚出现苗头的时候就可以发现,而不是等到大盘出现波动才发现。所以这个模型的关键在于分析决策的过程中,它会基于用户的人群特征、问题特征把线上采集到的不可用问题进行聚合再进行分析,通过预制的一些算法模型和规则来判断是否产生了异常,如果最终判断的确有异常产生了则会输出一个异常事件。
举个例子,比如线上的某个业务发布了一个新的H5离线包版本,其中某一个页面的卡死率很高。那么使用这个页面的用户就会形成一个特征人群,这个特征人群的页面卡死率就有异常的波动,这个时候就会输出异常事件。但是此时大盘并没有太大波动,因为特征人群的人数并不多,但是后台可以捕获到异常事件。当异常事件输出之后,可以通过附带信息准确地匹配到相应的负责人以及开发、测试人员,告警系统会告知负责人进行处理,并且会根据问题的严重程度采取不同的告警方式,可能会采取邮件、钉钉或者电话等方式进行告警。在问题非常严重的情况下,如果几分钟之内没有响应就有人打电话给负责人了。通过这样的告警机制就可以保证无论在什么的时间,只要线上出现异常问题就可以迅速地感知到。
高可用容灾平台
通过上述的内容,已经可以实现对于可用性问题的感知了。接下来分享如何通过高可用容灾平台修复异常问题。这里通过整体的故障容灾过程进行分享,如下图所示,当一个故障进来了,会向相应的负责人发出告警,这时负责人需要检查这个故障是怎样产生的,到底是由于线上变更导致的,还是由于客户端本身的Bug导致的。如果是因为线上变更导致的则比较好办,因为现在的系统比较灵敏,只要故障刚一发生在短时间内负责人员就可以收到告警,之后就可以到发布记录中检查这段时间内发生了哪几次变更,可以很快地基本了解是哪一次变更导致的故障,并采取相应的处理策略,如果可以回滚就进行回滚操作,不能回滚就需要进行紧急发布,如果不能紧急发布就要依赖客户端进行修复。
比较麻烦的是和变更没有关系的情况,此时就需要通过异常携带的诊断信息或者通过获取一些日志来检查问题为什么产生,问题的产生有时候是因为兼容性问题,比如某个厂商灰度发布了一批和支付宝兼容性不太好的系统,导致出现了各种各样的问题,这种情况下就要通过动态修复解决;也可能一些客户本地出现了严重错误,比如说产生了一些脏数据,或者安装时因为市场的临时性Bug导致了大量安装失败,最终导致支付宝打不开,对于这种情况而言,可以通过本地容灾做一些恢复工作,进而实现客户端的自动恢复。总之,通过上述的过程,可以使故障得到解决。从下图中可以看出,支付宝在高可用容灾中致力于两点:第一,希望每个故障都有一个对应的方法能够实现修复;第二,希望流程尽量清晰并且顺滑,希望不要在流程上浪费太多时间,并且将故障尽快地解决掉。
高可用的动态修复体系
移动端高可用和服务端高可用的重大区别就是移动端的发布比较困难,所以需要依靠动态修复技术。动态修复并不是新的概念,像hotpatch等技术都已经非常成熟了,目前也有很多可选的动态修复方案。但是,虽然在高可用的动态修复体系中,hotpatch属于比较重要的点,但是并不是最主要的点,因为它也存在一定的局限性,也有不适合的时候。目前,支付宝基于多种修复手段搭建了高可用的动态修复体系。
支付宝的高可用动态修复体系主要由以下三部分构成:
修复手段:修复手段有很多种,并且有轻有重。轻的手段在线上进行一些配置就可以解决线上不可用的问题,重的手段可以把整个模块完全重新部署下去。具体应该选择哪一种修复手段应该根据故障的情况来看,选择效率最高、风险最低的修复方式。
下发通道:这一点与埋点上报的要求有一点类似,也需要高实时性和高可靠性。当用户已经不可用了,常规方法拉不到线上的修复方案的时候,能够解决的办法再多也是没有用的,所以需要保障无论面对多么恶劣的情况下都能够把修复方案拉下来。下发通道的实现方式有很多种,最终实现只要能够联网一定可以将修复方案拉下来,如果暂时不能联网,那么一定要在联网之后将修复方案拉下来。
发布平台:设计动态修复的发布平台的时候非常关注的一点就是把修复方案推送给真正需要它的用户,也就是把修复方案推给已经出现或者可能出现这个问题的用户,这样做的原因是每一次的动态修复其实也是一次线上变更,本身也是存在风险的,如果对于所有用户都进行推送则需要比较长的时间进行灰度来保证安全,但是如果能够只对目标的小众人群、特征人群推送方案,这样灰度时间会很短,修复时间也会很短。支付宝在客户端请求修复方案的时候,会根据客户端的人群特征、是否发生过这个问题以及有没有发生这个问题的可能来判断是否把这个修复方案推送给他们,这样可以很快地完成推送过程。这在图中称之为“智能修复”,其实称之为“定向修复”更为准确一些。
高可用实战经验
在这里和大家分享支付宝在高可用实战中的两个案例,其中一个处理的比较成功,另外一个则不是很成功。
案例1:一个业务运营推送了一个错误的菜单配置,而客户端没有做好保护。在运营推送配置的10分钟之内,相关的负责人都收到了报警,并且很快地查到是这个配置导致的,之后运营将马上对于配置进行了回滚,这个过程所影响用户数比较少,所以是一个比较成功的案例。这也是支付宝最期望的运维过程,实现了及时发现、很快修复并且影响用户数很少。
案例2:在一次大促的时候,一个业务开启了限流,客户端弹出一个限流的页面,但是这个页面有Bug,会导致黑屏,进而导致用户无法进行操作。但是由于当时的可用性监控不完善,所以这个问题没有被监控到,最后是因为用户的反馈才知道出现了问题,到问题出现的第三天,反馈量已经积累到一个明显的程度了,才发现这个问题。之后,我们迅速地对于这个问题进行了分析和解决,最后定位到限流的问题,一个小时之内确定了问题所在,并暂时把限流先关掉,后来把这个Bug修复掉了之后再将限流打开,这样客户端才恢复正常。虽然最终把问题完善地解决了,但是这一过程存在非常明显的缺陷。首先是发现的太晚了,这是因为可用性问题没有覆盖到;另外,因为没有足够的信息使得决策的过程比较慢,花了1个小时进行分析才能够止血,直到现在我们也不知道这三天到底影响了多少用户,但是这一事件肯定对支付宝的可用性造成了不小的伤害。而现在,支付宝实现了移动端的高可用,以后像这样的事情不会再发生了,当出现故障时,支付宝可以在第一天很短的时间内就可以搞定问题。
故障演练
有这样一句话“避免故障最好的方式就是不断演练故障”,所以我们要通过可控的成本在线上真实地模拟一些故障,进行故障演练,检验高可用体系是否可靠,同时也让相应的同学对系统、工具和流程更加熟悉,当真正发生问题的时候可以快速地处理。
为了更好的检验这套东西,支付宝采用了攻防对抗演练的方式,成立了一个虚拟小组,他们会想办法模拟线上可能出现的故障情况,而另外一组人则利用移动端高可用技术接招,把对方研发的问题快速地处理掉。这样做好准备以后,当真正出现故障需要进行处理的时候,我们也已经能够熟练地应对了。
在前进中探索
最后再谈一下对客户端可用性运维未来的思考:
智能化。前面提到了高灵敏的模型,大家可以看到其实在决策的过程中往往需要依赖预设的算法模型、规则以及数值等,这些都源于常年积攒下来的经验。但是这也存在一些缺点:一是有可能出现误报;二是为了防止误报太多,这个模型不敢做的太紧,所以模型的灵敏度属于比较灵敏,而不是极度灵敏。我们期待通过智能化的方式,通过人工智能、机器学习的方法实现决策过程的智能化,可以做得更加灵敏,将问题发现的时间再提升一节,而且这目前已经不仅仅是一个想法了,在支付宝的很多场景中已经开始使用智能报警了,我们也在调研和尝试接入这个东西。
自动化。这部分主要指的是容灾过程的自动化。我们想把前面展示的容灾过程做的很顺滑,但是其中很多步骤都需要人来做,这样时间成本、决策成本会很高,所以我们希望把尽量多的步骤转成自动化方式,至少是半自动化的方式,这样才能让容灾过程更加顺滑,使得修复时间产生本质的飞越。
产品化。我们希望当客户端可用性更加成熟之后赋能给其他类似的APP,通过这个过程积攒更多的经验,发现更多的问题。并且在未来合适的时间,或者3.0版本的客户端可用性不能满足需求的时候再去建设4.0可用性运维体系。