本文从产品和架构演进、性能及稳定性挑战与优化实践、超级APP运维体系、架构上的容灾规划四个方面分享了支付宝APP亿级用户的性能稳定性优化及运维实践。性能方面,主要介绍了性能、电量、流量、内存、存储五个方面的优化。稳定性方面,主要介绍了Crash优化和稳定性优化。
直播视频:点此进入
PDF下载:点此进入
以下为整理内容:
支付宝介绍
刚开始的支付宝内容非常单薄,只有转账、缴费、话费充值。经过五六年的努力,现在的支付宝已经变成了整个蚂蚁金服承载金融业务的一个重大平台,承载着非常丰富的场景,也将作为未来生活互动的大平台。在未来,支付宝希望能够输出金融的能力,和大家一起完成普惠金融的梦想。
APP架构演进
在产品发生巨大变化的同时,技术架构上也发生了巨大的变化。总体来看分为三个阶段:
第一个阶段集中在2013年以前,支付宝从架构上来看是一个简单的分层、单体应用,上面是很多业务模块,下面是工具库;
2013年到2015年,最大的变化就是支付宝变成了一个服务化、模块化的应用,这样支付宝可以被多个团队并行开发;
2015年之后,我们发现支付宝不仅需要面对支付宝内部的各个部门做功能模块的开发,而且各个行业的应用都会往支付宝上去投放,整体来看是一个多应用的生态。技术上主要实现了开放和动态化,动态化是指不同的应用能够很快速的开发并且投放到支付宝上来,而且能够分发到不同需要的用户上去。对于超级APP来说,关键的一个设计是高可用、高性能、高灵敏度。
支付宝整体的架构和其他公司相比有很大的区别,支付宝采用混合型架构,包括:支付型架构、移动互联网金融型架构、生活互动型架构。
技术挑战
业务复杂性
支付宝在用户规模、功能的复杂度上远远超过了其他的APP。
设备多样性
性能问题的范畴
在支付宝内部有一个专门的团队负责支付宝性能优化,狭义的性能是指启动时间、流畅度、卡顿。除了传统的性能问题之外,还有流量、电量、内存、存储等广义的性能问题。随着业务的发展,未来广义性能问题会变得越来越重要。
卓有成效的性能优化实践
性能优化:一个应用达到很大的规模之后,以前讨论的单点优化的意义变得不大了,因为能优化的都已经优化的差不多了。支付宝内部有一个模块化的容器quinox可以支撑大规模同时的并行开发,其最大的优化就是改成了按需加载。通过线程治理,重新梳理了线程池设计、资源管控、CPU调度的思想。性能优化的一个重要部分是虚拟机dalvik的调优,包括关闭jit让应用的第一次启动加快、去dexopt。主线程优先级调整让主线程更快的跑起来,对其他线程的nice值进行调整,启动流程重构,引入pipeline机制把启动过程按序区分出来,使启动过程变得干净的同时方便监各部分控耗时情况。
电量优化:系统兼容性优化、业务优化,技术基础优化,特别是Wakelock,一个应用如果申请了Wakelock但是由于某些原因没有释放,这时候就会发现CPU一直没有休眠导致手机的耗电量一直在增加。
流量优化:所有的资源都做了增量/差量下载,让以前需要下载的全量的包变得小很多,对支付宝的应用进行按需下载,底层技术上做了RPC及整个底层网络协议的优化。
内存优化:主要把一些很耗内存的图片转移到Native上,虽然总的内存不会变,但是流畅度有很大的改观。并且对内存泄漏、对象占用做了深入的梳理。
存储优化:对so编译使用了STL共享库,Bundle中非必需的lib转移到assets上。研究新的压缩算法对日志进行压缩。
电量优化
怎么去衡量电量是一个专业的问题。支付宝采用两个指标衡量耗电:支付宝现在的耗电排名是多少?支付宝客户端耗电的占比是多少?经过排查,发现耗电的原因包括:CPU的使用率,过载线程会导致CPU的占用时间变长;各种sensor,gps;wakelock,网络连接。先进行耗电异常捕获然后再进行耗电优化。比如,当CPU耗电过多时我们希望知道哪个线程引起的,当我们发现支付宝的耗电量排名第一并且耗电占比10%甚至20%以上时,我们就把支付宝客户端里面所有线程dump出来,当dump线程调用栈的时候,操作系统会告诉你每一个线程耗了多少CPU的时间,这是一个非常重要的线索,我们可以从中定位出是哪个线程的哪行代码在消耗你的CPU。
流量优化
具体原理和电量优化类似,引入了一个流量指数的概念来评价用户在使用支付宝客户端时的流量消耗。参数包括总流量的和、不同访问请求重复的次数。
内存优化
比较大的一个技术改进是把整个支付宝客户端的内存在底层归属到不同的模块中,然后分析每个模块的占用是否合理。
稳定性
稳定性问题包括:启动闪退、启动卡死、Crash、ANR。
Crash优化
随着用户量的增长,传统的鉴定Crash的方法需要做一些调整。我们需要关注的问题是每天有多少人因为稳定性问题使用不了支付宝。所以我们把以前Crash的单纯定义做了一些细化,将总体的Crash细化为一次性的Crash和持久性的Crash,期望将持久性的Crash降到很低。另外,考虑到后台Crash对用户的影响还是可控的,所以我们还将Crash分为前台Crash、后台Crash。除了Java层的闪退之外,对Native层的闪退关注是更多的。
稳定性优化
思路与其他一样:监控、诊断、修复。为了把对用户的影响降低到最小,对启动过程中的闪退做了一些容灾措施,比如,发现一个用户连续三次都启动不了,则自动清理非隐私数据保证下次启动顺畅。
超级APP的运维体系
线上异常监控
在客户端,把一些关键的流程上通过切片技术布置监控点。在服务器端,当问题出现时能够将其模块化并且自动报警,通知不同的团队其健康状况。在数据分析上,利用各种图表、维度将数据展现出来,让用户能够看到均值、分布、尾部,方便出现问题时进行回滚。
电量指数的计算
Android4.4之后,系统将电量权限收掉之后,电量计算成为了一个难题。目前的方法是模仿整个Android系统计算电量的公式重新做了一遍,即首先从BatteryStats.bin中拿到每一个维度的权重,将维度和权重结合就可以算到Android系统的耗电量。
快速定位与诊断
每个部分出现问题的时候,比如CPU出现问题的时候把线程的调用栈打出来,并且获得线程消耗的时间,这样才能得知那个线程消耗时间比较多。
多层次的动态化技术
支付宝的动态化技术不是单点的,而是层次化的。从上到下分为五个层次:
配置同步(rcs):很多场景只需要一个配置就行,这是最基础的一个动态化,但是很有学问,怎么保证配置能够快速到达客户端?中间怎么去同步?
H5:用来做开放和承接外面的业务,以及支付宝内部要求不是很高但是动态化要求比较高的业务。
跨平台框架(hcf):如果对性能有要求的话,使用跨平台框架,用来兼顾开放、动态化、性能的要求。
Hotpatch:用来支持代码修复。
Native:支持把整个Bundle替换掉。
架构的容灾能力
在服务器端出现问题时,可以通过回滚等方法及时修复,但是在客户端出现问题时会比较麻烦,所以需要从架构方面对整个容灾能力做新的规划。把客户端出现的各种异常做一个抽象,然后提取出来各种特征,在服务器端针对这些特征配置相应的应对方法。