前端可用性保障实践

  • 本文转自美团点评技术学院,未经做者许可,不容许私自转载。
  • 美团云知乎机构帐号每日分享云计算产品,技术内容。 欢迎关注!
  • 加入美团云技术交流群(QQ群:469243579),每日分享更多精彩技术文章。

如何定义前端服务可用性

通常可用性都是说后端服务的可用性,都说咱们的服务可用性到了几个9,不多有人把可用性放到前端来。其实对于任何一个有UI交互流程的业务,都会有前端服务可用性,后端的可用性作的再高,前端一个按钮写的有问题点击不起做用也会致使用户没法完成流程。

前端服务可用性包含三个部分:
  • 前端代码可用性(测试质量,线上异常)。
  • 静态资源服务可用性。
  • 网络链路可用性(DNS劫持、网络性能)。
既从业务后台服务往上,一直到用户界面,一切都是前端服务,这里面一切用户可能遇到的问题都是前端可用性的范畴。

这就是咱们认为的前端可用性,收银台的可用性建设就是围绕着这三个部分展开的。

如何衡量前端服务可用性

前端服务的可用性衡量和后端的衡量方法相相似,不考虑影响范围大小,只考虑存在故障的时常,最大化考量可用性。可用性指标不是为了让咱们经过复杂的算法来减少事故对可用性计算的影响,而是为了激励咱们在可观测范围内作到没有问题,越作越好。影响用户数、影响订单数、影响GMV等指标更多的是用于作事故定级。

哪里容易出问题

前端代码可用性:
  • 空指针问题是困扰前端的一个大问题,因为JS自己是弱类型动态语言,没法在开发及编译过程当中经过工具推导出可能出现问题的点,进而在前端研发过程当中很容易疏忽形成空指针问题;
  • 业务逻辑覆盖率,指的是在业务项目当中,代码对动态逻辑的处理能力,每每在一些复杂的业务项目当中,逻辑混乱交错,前端的展现和进一步的动做由后端控制,这种状况下复杂的逻辑交织在一块儿产生无数分支,逻辑环境难以模拟,进而很容易在逻辑的处理上产生疏忽;
  • 兼容性,问题困扰着各个端的研发,对于前端来讲,要面临的环境更多,包括平台、系统版本、浏览器版本、WebView版本、Hybrid桥版本等等,很难从测试角度所有覆盖。
静态资源服务可用性:
  • 前端静态资源服务链的稳定性,例如NGINX、Node等等;
  • CDN并非任什么时候候均可以正常提供服务的,可能会遇到SSL证书链问题、回源服务可用性问题等等。
网络链路稳定性:
  • DNS劫持是一个老大难问题,大部分状况下是运营商为了节省跨省流量结算的费用而进行DNS劫持,走内部的缓存,还有一部分状况是广告,想象一下把收银台的代码劫持并插入一个运营商广告是有多可怕。
大块的问题就是上述几种,细枝末节的问题就不在这里一一细表,那么具体咱们是怎么解决的呢?

怎样保障才能使人信服?

记得刚刚开始负责支付业务的时候,老板(rank)常常问一个问题:“收银台稳定性怎么保障?”,我当时想的就比较简单,无非就是流程保障、测试保障等等,但这不是老板想听的,否则他也不会老问我,显然是当时没有回答出他想要的答案。如今想一想真是“too young too simple, some times naive”。

在美团点评,收银台是一个横向的业务基础服务,是全部业务的闭环环节,全部线上业务交易的最终环节所有由收银台来完成,它的重要性不言而喻。对于收银台来讲,有三点须要保障,这三点分别是可用性、体验和安全,它们共同为一个指标服务,那就是“支付成功率”。其中,对支付成功率影响最大的就是可用性。

可用性对支付成功率的影响有多大?

一个小小的bug上线后即便及时发现并回滚,可能也会形成几百上千万营业额的损失,这对整个团队来讲都是没法接受的。因此,对于收银台来讲,保障可用性是第一优先级。

同时,支付做为一个特殊的业务有它对可用性独到的要求,在可用性保障上必然不是任何业务都会用到的那老几样儿。老板想听的是对稳定性保障的独到看法,可复制的方法,有可用性保障的理论基础,让任何一个往后负责这个业务的人都可以照方抓药,保障前端服务的稳定性。

如今总结起来可用性的保障分为三个阶段:
  • 事前
  • 事中
  • 过后
保障手段分为三个大类:
  • 软的
  • 硬的
  • 根源的
“软的”是指用“人”来保障的部分:
  • 流程保障
  • 规范保障
  • 测试保障
……

“硬的”是指用“工程工具”来保障的部分:
  • 静态代码检查
  • 单测
  • Web自动化测试
  • 持续集成
  • 线上前端异常监控
  • 业务异常监控
  • 前端服务异常监控
  • 网络异常监控
“根源的”是整个可用性保障的核心,是指经过“技术选型”来让系统更健壮,这里面有两个核心点。

技术选型要简单稳健

要求在具有伸缩性的基础下避免任何复杂的不可控技术方案。核心链路上的全部代码,团队要具有维护能力,要减小外部依赖。

这里面有一个关键的选型概念就是“场景契合度”,技术选型不是你愿意用什么,你熟悉用什么,是在这个业务场景和团队规模下须要你用什么。

举个例子,收银台是一个单页应用,之因此设计成单页应用是由于它涉及到的视图跳转和数据传递太多,单页应用相比多页更具优点。那么在选型的时候咱们当时有React、Angular、Ember等一线前端SPA框架能够选,但最后咱们仍是本身作了一个简单的视图生命周期管理工具,为何?

“场景契合度”,React和Angular等前端框架更适合极端复杂的大型单页应用,为了可以更好的处理这种复杂度采用了一系列厚重的工具去约束研发的过程,其中还包含一些这个项目不会遇到问题的优化,例如渲染优化等等。对于收银台来说,单个视图中的复杂度并无那么高,能够遇到前端渲染性能瓶颈的项目并很少。
“源码维护能力”,收银台做为核心链路中的核心业务,在技术上绝对不容许被动,团队必须具备核心代码的维护能力。而依照咱们当时的团队规模,这是不现实的。
在收银台这个SPA场景里,咱们只须要视图生命周期管理这个功能。因此,咱们参考Cocoa View Controller的生命周期设计实现了一个简单的单页视图工具“Cyra”,它只负责视图生命周期的管理,简单、拓展性高、源码可维护且无外部依赖。

避免出现核心链路上的可用性短板

举个例子,网页首帧渲染优化有三种常见方式:
  • 手工预渲染
  • 编译预渲染
  • 服务器预渲染(SSR)
其优化的核心内容就是把尽量多的首帧渲染所需信息在第一个请求的响应中给出,也就是主文档请求,让用户可以尽量快的看到内容。

从优化效果上来说,SSR的效果最好,它能够把JavaScript(如下简称“JS”)、CSS、HTML之外的动态的数据一块儿经过第一个响应返回回来。

可是,最后咱们选择的是编译预渲染,为何?

先说什么是SSR。这个概念是新提出来的,但原理很早就存在,相似JSP、ASP这种技术早年间一直都是SSR,在服务器端把页面拼装好传递给客户端。和佛家的人生三境界同样,禅中彻悟后又回去了,就像如今的前端服务化很难作到当年微软ASP.NET Web Form那个水平。

后来前端行业发展迅速,发生了两个大的变化:

你们开始作先后端分离,把静态资源单独管理,好处就不说了,有一个弊端就是当用户浏览器把静态资源下载下来后可能还须要另一个请求去获取这个页面上的动态数据;
前端工程化的兴起,你们会把CSS JS HTML结构统一打包到一个JS文件中,HTML中只有JS的引用,这样就致使HTML下载完成后仍是白屏,只有等到这个巨型JS下载完成后首帧内容才开始渲染。
这时就用到了SSR,通用作法是增长一个Node层,在服务器端作首屏内容的拼接,包含静态数据,这样可以保障首帧渲染不只快,还包含首屏所须要的数据。

能够看到,Node这一层在咱们界面请求的核心链路上,Node自己的可用性和上下游的服务相比要差不少,其自身的稳定性须要许多其余工具去保障,那么对于这块业务来讲,Node这一层成为了“核心链路上的可用性短板”,这样即便背后的各个后端系统可用性再好,只要Node这一层挂掉就会形成用户没法访问的问题。

因此基于“避免出现核心链路上的可用性短板”这一层考量,咱们退而求其次选用“编译预渲染”,在编译期间把首屏结构所有拼装好,这样可用性就获得了保障。

关于Node在服务端的应用上,我认为其实大多数状况下,不用要比用要可贵多,关于这方面的一些思考能够详见后续文章《服务端为何不能用Node》。

理论有了,咱们是怎么作的?

“软的”流程规范部分就不展开讲了,各个团队都差很少,只不过是完善不完善的差别。接下来主要讲一下“硬的”部分。

前文提到,“硬的”保障主要指的是工程工具的保障手段,工程工具不少,这里对应前文几大问题的顺序,讲一讲咱们的解决方案。

前端代码可用性部分主要有三个容易出问题的点:空指针、业务逻辑覆盖率、兼容性。

空指针

“空指针”部分的问题解决只能从语言自己来解决,JS自己是弱类型动态语言,没法在开发及编译过程当中经过工具推导出可能出现问题的点。针对这一点咱们从2015年开始实践TypeScript(如下简称“TS”),当时也看了Facebook的Flow,但当时Flow还不够成熟,因此没有选用。

引入TS后,将咱们的弱类型语言变成强类型语言,从编码过程当中就能够帮助过滤掉很大一部分空指针问题,TS强大的类型推导系统能够帮咱们分析出系统中的空指针隐患,进而能够解决线上99%的空指针问题。固然TS还有不少其余好处,这里就不展开了。

业务逻辑覆盖率

“业务逻辑覆盖率”这个问题的背景再也不赘述,因为收银台的复杂度高、case多,复杂状况下的后端状态很难模拟,所以只能采用自动化工具去解决,这就涉及到了“Web自动化流程测试”。

Web自动化流程测试在这种场景下除了能够验证case的正确性之外,最重要的功能就是要有一个异常强大的case管理模块。业界目前并无理想的工具可以支撑咱们的场景。

美团点评内部有一个咱们参与需求的Web自动化流程测试工具“Freekite”,它在case验证功能的基础上,有一个强大的可视化case管理模块,支持复杂的case细分。除了界面操做的细分外,能够全量Mock或部分Mock后端的数据响应,根据响应拆分出不一样的case分支。除此以外,还包含智能自动化断言功能,断言基本不须要人工参与。

可能有人要问了,这个case录完之后万一遇到界面改版怎么办?不要紧,虽然有强大的类似度匹配功能,Freekite还支持单独节点的从新录制,也就完美的解决了case的维护问题,大幅度减小工做量加强效率。紧接着咱们会在项目中增长Freekite的持续集成,在项目的每个阶段进行流程上的自动化回归验证,业务逻辑覆盖率的问题就基本解决了。下图为Freekite可视化Case管理。

兼容性

“兼容性”问题公司内部有云测平台,能够快速在多机型真机上回归主要流程,能够经过云测平台覆盖占有率95%以上的各类机型。然而兼容性也是同样,须要从根本上选用一个可靠的选型,从而避免在处理兼容性问题上会遇到的拆东墙补西墙最后仍是不放心的尴尬境地。兼容性问题在移动端除了布局外主要出如今两种操做中:点击和滚动。

前文描述的自主研发的单页视图工具就以最简单的div隐藏显示的方式来处理视图切换,使全部元素处于正常的文档流当中,点击处理也经过分级降级的方式最大化平衡体验和兼容性,从而保障了整个项目的兼容性。

静态资源服务可用性主要就是NGINX层的健康检查及CDN的回源监控,这一点公司SRE有强大的系统支持(有关美团点评SRE的实践能够参考以前的博客文章),这里就很少讲了。

网络可用性上最头痛的问题是DNS劫持,前文讲到了DNS劫持方面除了恶意劫持之外,主要是运营商以节省跨省流量结算费用为目标进行DNS劫持。当运营商系统发现HTTP访问的域名时会在区域内的服务器中缓存一份资源,后续用户再请求的时候其域名解析会被解析到运营商的服务器上去由运营商的服务器直接返回内容。

其应对方法只有使用HTTPS,但并不只仅是在原有的域名HTTP的基础上切换HTTPS那么简单,还须要保障这个域名不支持HTTP访问而且没有被大范围使用HTTP访问过。若是不这样作的话会出现一个问题,运营商在DNS解析的时候并不知道这个域名是用什么协议访问的,当以前已经记录过这个域名支持HTTP访问后,无论后续是不是HTTPS访问,都会进行DNS劫持。这时若是使用的是HTTPS访问,会由于运营商的缓存服务器没有对应的SSL证书而致使请求没法创建连接,从而遇到请求失败的问题。在以前业务切换HTTPS的时候就遇到了这个问题,请求成功率从99.96%下降到了96%,花了大量的时间去定位问题。当切换了全新的域名后这个问题才获得了解决。

在过后方面,除了强大的支付后台业务系统监控外,公司还有完善的通用监控系统,例如异常监控系统能够分级分批上报前端的JS Error及自定义异常,性能监控系统Performance能够了解前端的访问状况作性能分析,网络监控系统CAT能够快速定位网络层性能情况、区域DNS劫持情况等。



做者简介

禹霖,美团点评前端技术专家,负责金融钱包及支付前端团队。
相关文章
相关标签/搜索