写在淘宝325热度之后

By | 2020年4月2日

①引言

2020年3月25日对绝大多数人来说只是个普通的日子,但对于淘宝的iOS团队来说,这注定是一个难忘的时刻。

②现象

凌晨时突然收到iOS朋友群里发来的上图,惊呆了,顺便在9.1.1版本上操作了一波,并没有重现,以为是个恶搞。

睡前想了一下,手淘理论上是不应该犯这种低级错误的,直到第二天早上发现所有的iOS群几乎都在讨论这个问题,才意识到这是一个非常严重的问题:

“您使用的程序是内测版本,将于当地时间2020-03-28到期,到期后将无法使用,请尽快下载最新版本”,这个bug第一次修复的成为了一闪而过弹窗口,有兴趣的话可以点击【淘宝325视频】查看具体现象,综上这是一个非常明显的首页弹框线上故障。最后通过发版解决的话,算上加急审核时间,至少8-12小时已经过去了,由于公司已经封口,至于故障最终定级到P几,这个只有内部同学才知道:)

③行动

怀着对线上问题的敬畏心,立刻以粗略的脑图记录下了当时的思考过程。同时为了照顾到部分读者本文会以较通俗化的语言从多个角度来评价这个问题。

关注公众号并回复关键字“脑图”即可获得当时的高清脑图,由于是第一时间写出来的东西,有考虑不周的地方也请见谅,更希望大家也能一起踊跃讨论。

④分析

问题出在哪里?
1.启动弹框无法关闭

2.热修复(hotfix)无法根治,现象为hotfix后弹框依然一闪而过。
3.只能通过发版解决。

熟悉iOS运行机制的同学通过App的启动运行机制,也许能猜到以下这几点,咱们一起来抽丝剥茧:

1.首页弹框的优先级应该是非常高的,结合隐私法,这个弹框的优先级应该仅次于App启动时的隐私弹框。

2.通过第1点,hotfix的代码有可能放在首页弹框代码逻辑之后进行了初始化,导致无法热修复。
3.在hotfix后弹框模式依然为单按钮的警告弹框,但弹框文本已发生改变,猜测文本内容是由接口返回并在弹框中展示,当然也有可能是hook弹框后通过消息钩子来修改弹框文本内容。

4.hotfix独特的下发和触发机制,有可能会因为网络问题(无法下载)、手机内存问题(无法保存)和一些用户不知道如何冷启动(即杀掉淘宝进程再重新进入app),导致无法快速覆盖到所有被影响到的用户。

5.由于AppStore上淘宝的最低支持版本已经到了iOS9.0,而UIAlertView在iOS9.0已经被废弃了。

6.根据第3条猜想既然能hook修改文本框内容,为啥不直接return让弹框连显示都不显示呢?是不是直接return后,有接口级别的上下文依赖呢(配置下发)?

7.既然弹框的时间可以改,那是不是就能证明这个弹框是是动态配置的呢?

是不是可以一直猜测下去?对于技术有着细节完美追求的人可能还能再总结个十条八条的,手上没有越狱机器,也懒得去下载已脱壳的ipa,因此对于这个弹框是否是可配置的咱们先打住,但可以肯定的一点是这个弹框是没办法在App启动时强行关闭的。

个人的猜想还是这个弹框关闭后所涉及到的接口内容可能对下文有强依赖,不能直接return,否则可能产生更多棘手的问题,因而在hotfix阶段采用先展示后关闭的方式来进行必要的数据传递。

问题分析到此告一段落,接下来我们来看看什么是首页弹框,它的用途、技术实现及潜在的缺陷,以及发生问题的情况下如何应对。

⑤什么是首页弹框

一、用途:看过325弹框的同学应该有非常深的印象了,那么这个弹框通常被用在App启动页,其目的是用来告知用户进行一系列的操作,比如软件更新、营销广告、浮层引导等提示引导。大家打开App时展示的隐私协议、更新提示及相册、通讯录、麦克风等使用权限其实就是非常典型的首页弹框使用场景。

二、运行机制:保证弹框在首页需要的特定场景可以弹出即可,由于电商、社交、游戏等类型的App弹框的业务类型各不一致,因此各类弹框的时机也会有一些差异,具体业务具体分析,此处不再赘述具体流程。

三、技术实现:由于业务的差异化,技术选型也会存在不一致的地方。举个栗子,隐私弹框在App第一次打开的时候只显示,那么就需要考虑这个弹框在App端是否需要写入一次,多次读取,既然涉及到了缓存,那么就得考虑缓存的写入判断及缓存清理等操作,不要小看了这个问题,曾经遇到过因手机磁盘空间满而无法写入导致弹框反复出现的问题,相信在一些小公司或伪互联网公司里,这一条测试case是比较难贯彻的。

四、弹框可配置:由于运营、风控、安全、隐私、评价等业务的团队都会用到这个弹框,因此做好弹框的类型、优先级尤为重要。重点交互接口必须做到可回滚、可降级且增加权限判断(可以参考银行的交叉业务鉴权/授权进行设计),弹框的频率控制也需要考虑在内,通常关注维度不局限在次数、时间上。

另外弹框文案、颜色、字体及路由目标地址必须可配置化并增加规范性检查,必要的时候风控介入。必要时请对弹框内文案的合规检查,亲身经历曾经某平台发布了违规物品信息导致收到警方要求提供发布者ip。

五、数据监控:无论产品经理是否对弹框做了数据收集,研发人员都应具有数据收集和分析意识。必要的数据能够让研发非常快速的定位到问题,比如弹框预期展示多少次,弹框被打开和关闭的次数,按钮被点击的次数,弹框被展示时的时间、时长等,接口的平均请求、响应时长,95/99线,以及userid(请记得加密),ip,idfv等共通数据。如果有兴趣的话可以增加热点区域的观察数据,会有惊喜的发现,在一些电商类app中,hotspot是非常重要数据支撑。

大胆设想一下如果这次淘宝325的弹框有预期值并且设置警报阀值,也许解决的速度会更快,毕竟0点到6点苹果的审核速度还是可以保证到的,大厂们通常都会和苹果公司保持一定的不正常审核通道关系:)

如果是权限控制类弹框,还需要注意业务逻辑混淆,避免被脱壳后快速注入的尴尬,优秀的产研人员都会通过分析数据从而对产品或技术进行业务或技术调整。

六、缺陷:首页弹框的用得好是个神器,用得不好是绝对是个恶梦级别的产品,以手淘325为例,光阻塞级别的用户体验就能让普通用户莫名奇妙,再加误导文案引起的卸载量,就能让增长、运营哭晕在厕所。试问在没有更新AppStore版本之前的hotfixed,有多少用户知道杀掉进程后再启动?其实我更想看到的是淘宝内部客诉电话量及接通率,这是一个服务性行业的硬指标。如果这个时候竞争对手再盯着这个点不放,如果不是疫情之下电商强大的生命力得以绽放,可能大阿里在商海中也要打个哆嗦。

上述仅仅只是对外的表现,如果没有对弹框做好业务规划,并对弹框分类、优先级及权限设置做系统化的梳理,那么无论是产品经理、技术负责人还是像我们这种生活在最底层的小研发小测试,都将是一场噩梦,身边做过相关弹框的产品换了一波又一波,吐槽的研发测试也不在少数,曾经一个被定级为P1的故障就是因为层级配置错误,导致弹框无法被关闭,虽然通过hotfix快速修复,一查数据15分钟内已经影响到了4w+用户。

⑥如何应对

一、技术层面
1.Code Review:老生常谈般的CodeReview必须建立在行之有效的代码规范检查上,对hard code零容忍。

记得07年的时候一个对日外包项目给小鬼子做系统,天天被诸如if和括号中间必须有空格、赋值语句等号左右两边必须加1个空格等极度琐碎的bugs(没错,小鬼子认为这就是bug)所困扰,实在受不了花了半天时间用正则表达式写了个检查工具,把这些代码规范一一实现后,省了很多麻烦事。

另外也请不要过度依赖代码检查工具,规范性检查无法验证业务逻辑是否正确,除非团队实施单元测试,重点业务逻辑请尽量团队Review,git权限做好管控,避免灰犀牛事件发生。这里推荐一个代码比较工具BeyondCompare,如果版本基线管控得当,这是一个神器,当然git也非常好用。

2.由于影响面非常大,因此首页弹框一定要做好权限管控,做到研发测试权限隔离、生产环境权限申请,涉及到的敏感操作操作需要二次审批或确认。如果公司内部能像银行那样做好二次审批授权的话,应该可以有效的避免类似之前微盟的运维事件。

网传手淘也有因iOS研发被325才搞出这等骚操作,针对此事不做过多的猜测,权当娱乐新闻搏君一笑,毕竟写代码还是非常枯燥的事情。至少故障发生时,AppStore半年前的iOS版本9.1.1是没有这个问题的:)

3.上文提到的热修复(hotfix)由于在苹果这边非常敏感,尽量考虑在有能力的前提下自研一套吧,经历过两家公司从打仗的高速业务竞争期到合并中的蜜月期,你会发现在此期间有个hotfix方案兜底,走路都带风,说话声音都大了。

上文提到的hotfix缺陷和自研的人员投入度及灰度问题,实在不行可以考虑RN或h5页面降级这样的伪动态化方案。flutter长期看好,目前github上已有flutter基于JIT在iOS下热更新的方案(性能略差),当然能否过审先在这里打个问号。

说了这么多hotfix,咱还是低调点吧,毕竟之前大神Bang的JSPatch之前被苹果爸爸打得鼻青脸肿,滴滴的DynamicCocoa更是被苹果爸爸吓得在github仅靠README.md就获得1.3k的Star,lol~

4.前面提到的数据监控,在Jenkins阶段就可以开始介入,用好定时job,类似Infer和OCLint扫描不能走形式主义,直接发送到各自业务模块负责人限期整改并kpi考核。

5.动态化、A/B、灰度、降级等策略是非常棒的实施手段,如果有精力,请记得一定构建这种能力体系。

最后,也请关注故障复盘、故障演练,毕竟这是成长的一部分。

二、其他层面

做为研发、测试,不能只管好自已的一亩三分地,如果组织架构足够复杂,那还需要考虑问题发生时同步通过运营、公关、法律、风控、财务、人事、行政等进行相关的处理,做好故障安抚及灾后重建工作。

题外话:要在阳光灿烂的日子里修屋顶,不要等到下大雨去修屋顶。——乡村教师马老师

抛个问题供大家讨论:客户端的高可用体系该如何建立?

最后祝愿所有读完本文的人都不会被325。