打破重重阻碍,手淘如何突破native crash提升稳定性?

简介: 本文是作者在 「Top100全球软件案例研究峰会」上分享的——手淘Native治理,结合分享后的反馈焦点,从 native 问题线下发现和快速定位、新so集成标准、线上历史native问题治理等几个方面为大家介绍,特产此文。

屏幕快照 2020-03-04 下午4.07.12.png

作者|潘文超(开风)
出品|阿里巴巴新零售淘系技术部

导读:本文是作者在 「Top100全球软件案例研究峰会」上分享的——手淘Native治理,结合分享后的反馈焦点,从 native 问题线下发现和快速定位、新so集成标准、线上历史native问题治理等几个方面为大家介绍,特产此文。

扫描下方二维码,关注「淘系技术」微信公众号,回复“native”即可获取本次分享完整版 PPT 资料!

qrcode_for_gh_4b3f15bce4d8_258.jpg

背景

屏幕快照 2020-03-04 下午4.09.53.png

无线客户端 crash 一般分为 java crash 和 native crash ,无线应用往往为了追求更好的性能,把一些复杂的计算放到 native 层去实现,java 层通过 jni 调用 native 层实现,满足功能场景;在 native 层产生的崩溃就产生了 native crash ;无线客户端衡量稳定性的最重要的指标就是 crash 率,稳定性一直是各系统治理的重中之重,也是一直绕不开的话题,而 native 是目前业界认为治理最有难度,也是要重点突破的方向。接下来分析一下为什么 native 治理值得去做以及如何做好。

▐ 目前手淘Android的crash现状——找方向

从图中我们可以看出,java crash 正常可以维持在较好的水平,手淘 native crash 一般比 java crash 要高,大促期间,由于手淘内存瓶颈, native crash 率会涨到日常水准的2-3倍。

从数据可见,native crash 是 java crash 的6倍之多,如果要想进一步突破,native 是有很大空间的,但 native 问题一般都很难定位, 堆栈不全,或者堆栈都集中在系统 so 上,无法直接定位问题,所以想要突破难度很大。手淘稳定性再上升一个台阶,native crash是瓶颈,需要突破。

▐ native crash 治理挑战——难

屏幕快照 2020-03-04 下午4.10.36.png

(1)难点一:crash堆栈目前绝大部分只有系统so,缺乏问题关联的业务模块so,定位问题难度大,可以看一下如下的一个native crash堆栈,堆栈中的so都是系统的,无法直接定位业务问题。

(2)难点二:线上so都是去符号化的,即使堆栈中有业务so,也需要记录该APP版本对应的符号化so做反解才能拿到能看得懂的堆栈。这点已经通过第一阶段的native工程标准化解决,打出来的SDK包里面必须要有对应的符号化so才可以集成。

(3)难点三:目前线下有效提前发现native问题的手段缺乏,想要提前发现,需要平台工具和有效手段。

▐ native crash 治理核心问题是什么?——找抓手

要治理、要解决问题,首先得理清目前导致 native crash 的问题,在做之前,做了一下 crash 数据分析,于是手动捞取了当时近5个版本的 top native crash 数据,占比最多的就是sig 6和sig 11。

那能说明什么问题呢?signal 6这种崩溃信号要看具体场景,但根据具体数据分析,手淘里面一般都是堆栈溢出、OOM 等导致的。signal 11 这种崩溃基本就锁定为内存问题了。

根据实际数据,大部分 crash 原因是因为内存,可以初步下的结论是,目前手淘 native crash 治理的关键是内存,解决手淘native内存相关的问题即可解决掉不部分问题。

Native问题治理平台工具调研

对集团内及业界的一些产品做了一些调研,详细如下:

屏幕快照 2020-03-04 下午4.11.04.png

分别从使用成本、功能支撑、是否有堆栈能力,性能如何等维度进行了比较,其实我们的诉求是希望不需要 root 就能 run 起来,因为我们要持续集成、线上能灰度验证,线下可以大规模任务执行、并且可以做手淘 native 问题沉淀,能把问题沉淀做成检查项,可以涵盖解决主要的内存问题,不止是内存泄漏。因此开发了Native Finder,希望能彻底治理好手淘 Native 问题。

Native治理——Native Finder整体技术方案

Native Finder是利用elf hook的原理,对malloc、free、realloc、alloc、mmap、munmap 等操作进行 hook,在自己的 hook 函数中,做一些智能分析和统计,并最后会调用系统内存操作函数,不破坏 so 原本发起的 malloc 等操作。

这个方案的缺点是会有一定的性能损耗,毕竟在 malloc 等操作中增加了一些分析和统计操作,但性能影响还好,在开了堆栈能力之后,APP性能会受影响,这个也是后面要优化的地方。整体技术方案如下:

屏幕快照 2020-03-04 下午4.11.46.png

native crash治理过程

屏幕快照 2020-03-04 下午4.12.22.png
首先在前期,花了比较多时间去研究历史数据及问题,认真分析 crash 的关键问题和痛点是什么,才找准了方向,分析出来内存问题是最痛的点。治理过程总结如上图,分为5个阶段。接一下讲详细介绍结合Native Finder工具平台的治理过程和心得。

▐ native工程标准化

治理总结如下:

屏幕快照 2020-03-04 下午4.12.48.png

总结起来这个阶段我们做了3件事情:

第一,库迁移,为什么要做库迁移呢?我们把老的gnu C++基础库迁移成libc++_ shared库,所有so都做统一,归一化,方便归一native层问题;

第二,我们还做了重复so治理,因为不同so可能依赖了相同的so基础库,举个例子,例如A so依赖了libopenSsl基础so,B so也依赖了libopenSsl库,但他们依赖的版本不同,这样带来的坏处是,首先会增加包大小,其次会有相同so的不同版本存在应用中,这给定位问题带来了麻烦,所以需要对基础so去重。

第三,每个版本包包括灰度版本都需要存储下对应的符号化so,便于在crash发生后,我们对堆栈做符号化处理,这样堆栈我们就能看懂了,加快和精准定位问题。这个阶段是后面做的所有事情的基础,非常重要。接下来我们看看下一个阶段治理

▐ Native Finder开发完成,线下monkey跑native问题

屏幕快照 2020-03-04 下午4.13.44.png

此阶段发现了几个堆破坏的问题,但是经过好几天反复线下执行 monkey,并未有任何进展。

后续调整思路,开始逐个分析线上存在的 native crash,并根据这些 crash 特征和根因开始沉淀经典问题,并把这些问题做成检查项,跟同学交流和对焦后。

通过进一步的数据,发现内存 OOM 是目前优先级较高,且比较严重的问题,所以开始做这方面的技术建设,跟 crashSDK 打通,Native Finder 中统计和分析 so 维度占用内存未释放的数据,在 crash 的时候做内存信息 dump,并输出辅助信息,例如 malloc、mmap 次数、大内存(大于2M,属于大内存申请,可配置,可动态调整)的申请等信息。接下来看一下线下monkey 驱动阶段

▐ 线上灰度,结合用户真实操作场景crash

屏幕快照 2020-03-04 下午4.14.06.png

线下 monkey 并不能都能复现问题,借助工具平台拿到关键信息去做问题解决和定位,我们希望场景更加丰富和多样,所以我们把 Native Finder 放到线上,做了线上灰度。

随即把 Native Finder 放到线上做外灰,在用户真实操作场景下的 crash,拿到 crash 时的内存 dump,但是经过一段时间的线上 crash 内存信息采集,然后分析之后,没发现明显问题,从现在回头看这个阶段,其实当时的数据是能够体现出问题的,只是当时的想法不对。

▐ 虚拟内存不足,是目前OOM主要原因

我们对线上crash做了分析,同时也在线下做了可疑场景的尝试复现,复现过程中,我们也做了大量数据的对比分析;

分析发现:正常 crash 跟 native oom crash,在内存详细数据上做对比,发现OOM crash 在 native vmsize 上有较大差异,又看了很多手淘 OOM crash,发现都是这个原因,vmsize 暴涨。

大家都知道,32 位系统下,系统 vmszie 只有4G,还要抛去一些系统内核占用、以及共享内存占用,vmsize比较有限,手淘又是一个体量很大的航空母舰,各个业务都想有最佳的业务体验,都想用空间换时间,每个业务泄漏那么一点,那手淘就被撑爆了,是累加泄漏的结果。

所以手淘 Android OOM 要一个一个解决,逐个挖出来,才能根治。我们整个过程沉淀了如下检查项:一共沉淀了8项内存检查,内存检查项已经能覆盖 80% 以上的内存问题了;fd 文件句柄检查项一共沉淀了6项,fd 的检查项已经能覆盖几乎95%以上的 fd 问题了。

我们同时也研发了本地调试模式,方便开发和测试同学,能快速在本地复现和定位问题,具体的技术方案如下:

屏幕快照 2020-03-04 下午4.14.06.png

▐ 开始陆续发现各种 native 问题

朝着这个方向,对 Native Finder 做了逐步优化,开始陆续发现各种问题,治理初步阶段,我们通过 Native Finder 工具平台一共治理发现 20+ 问题,其中包括了多种问题类型,例如内存堆破坏、内存泄漏、OOM、内存操作越界、多次free、内存操作错误等。

同时手淘日常的 native crash 率也有明显降低。到这里,我们 native crash 已经初见成效。虽然通过治理,陆续发现了不少问题,但是还远远不够,手淘内存问题依然严峻,特别是双十一场景下,互动、活动以及各种场景链路互拉的场景,内存问题还是很严峻,后续还需更加努力。

展望

接下来我们希望还能做的更多,现在才刚刚开始;手淘内存问题依然严峻,要彻底治理,需要建立卡口,发现问题自动加入必改问题池,形成良性循环,旧问题不断发现解决的同时,还需要杜绝新问题的引入。

除了 native so 导致的内存问题,当前 H5 场景的内存问题也比较严峻,去手淘随便拿几个 H5 页面,看一下内存增量,都超过内存标准,H5缺乏管控,下半年需要对H5内存做卡口严控;目前针对前端的内存泄漏,还没有有效的手段去检测发现,从native层看,都体现在内核上,内核应该是没有问题的,如果有效发现前端代码导致的内存泄漏,也是一个值得研究的点,不过先做卡口再做进一步突破。

屏幕快照 2020-03-04 下午4.16.08.png

今日吐槽

大家都在 native 治理上遇到哪些坑?
欢迎评论区留言,和小橙子分享哦~

We are hiring

淘系技术质量团队负责保障整个淘宝和天猫主站的业务质量,在这里有丰富多样的业务场景和技术挑战,以及很多优秀的合作伙伴。在这里你不仅能够了解世界级双十一是如何保障的,最关键的是有对技术极致追求,对生活的充满热爱的一群俊男美女们。
还等什么,赶紧加入我们一起共同打造淘系的技术质量。
请投递简历至邮箱:hane.yjr@alibaba-inc.com

关注【淘系技术】,一个有内容,有温度的微信公众号!

屏幕快照 2020-02-07 下午3.57.54.png

相关文章
|
18天前
|
运维 数据可视化 持续交付
如何解决技术债
本文介绍了技术债的概念及其影响。技术债是指在开发过程中因选择快速解决方案而非最优方法而产生的额外工作量。文章指出,技术债可能导致项目中出现如流水线失败、无用代码、难以理解的代码等问题。还强调了管理技术债的重要性,因为它会影响软件的交付速率和质量。有效的管理包括识别技术债、可视化问题、分析优先级、制定执行计划和持续改进。建议团队通过价值/成本矩阵来确定优先解决的技术债,并通过建立技术规范、服务责任人制度和持续关注技术趋势来预防和解决技术债。此外,应确保持续投入资源进行技术优化,并与团队和客户分享改进成果,以维持软件的高质量和稳定性。
58 1
|
3月前
|
程序员 开发者
开发者面对焦虑的缓解方式
焦虑是我们每个人在面对未来的不确定性和对自己的不满意时常常遇到的情绪,而且作为技术人员,我们往往面临着工作的挑战和高强度的压力,这可能导致焦虑情绪的出现。但是,作为一个正确的解决方式,一个正确的循环,我们可以通过一些有效方法来对抗焦虑,保持良好的心态和专注力。那么本文就来简单分享一下技术人对抗焦虑的有效方法有哪些,如何变焦虑为动力。
129 3
开发者面对焦虑的缓解方式
|
11月前
|
负载均衡 API 数据库
【韧性架构设计】软件韧性:从意外中恢复的 7 个必备因素
【韧性架构设计】软件韧性:从意外中恢复的 7 个必备因素
|
11月前
|
人工智能 安全 架构师
不了解持续架构会落伍么?
不了解持续架构会落伍么?
|
容灾 测试技术 调度
一对一直播系统开发,稳定的系统更具发展优势
一对一直播系统开发,稳定的系统更具发展优势
|
运维 监控 数据库
面对平台间业务的迁移,你该做些什么?
面对平台间业务的迁移,你该做些什么?
213 0
面对平台间业务的迁移,你该做些什么?
|
消息中间件 缓存 NoSQL
直播app开发,实现系统稳定性的难点及关键措施
直播app开发,实现系统稳定性的难点及关键措施
|
安全 网络安全 数据安全/隐私保护
面对未来网络安全 如何做到一劳永逸?
面对未来网络安全 如何做到一劳永逸?
面对未来网络安全 如何做到一劳永逸?
|
缓存 供应链 调度
系统从初期到支撑亿级流量,都经历了哪些架构上的演变?
随着互联网的发展,互联网企业的业务也在不断的飞速发展,进而导致系统的架构也在不断的发生着变化。总体来说,系统的架构大致经历了:单体应用架构—>垂直应用架构—>分布式架构—>SOA架构—>微服务架构的演变。当然,很多互联网企业的系统架构已经向Service Mesh(服务化网格)演变。今天,我们就一起来聊聊关于系统架构的演变这个话题。
158 0
系统从初期到支撑亿级流量,都经历了哪些架构上的演变?
|
监控 安全 数据可视化
宜信如何做到既满足远程办公的短时便利性需求,又不丧失安全性
宜信如何做到既满足远程办公的短时便利性需求,又不丧失安全性