BT

您是否属于早期采用者或者创新人士?InfoQ正在努力为您设计更多新功能。了解更多

Qzone前端团队的最佳实践:面向运营
录制于:

| 受访者 徐晓 作者 杨赛 发布于 2014年3月18日 | 智能化运维、Serverless、DevOps......2017年有哪些最新运维技术趋势?CNUTCon即将为你揭秘!
22:08

个人简介 徐晓,腾讯Web前端、海量SNS站点架构设计研发领域专家; Qzone核心架构开发人员之一,目前主要负责Qzone平台的Web前端研发工作。 曾担任Qzone3.0/4.0重构,日志重构的主力前端开发, 曾主导Qzone5.0,Qzone App管理,Qzone个人中心等项目的前端架构和主要前端开发工作。

   

1. 大家好,我是InfoQ的主持人,今天很高兴腾讯大讲堂帮我们安排到了徐晓接受我们的采访,那么请徐晓先做一下自我介绍吧?

徐晓:大家好,我是来自腾讯Qzone的徐晓,我是06年加入QQ空间这个团队。从事过比较经典的Web开发工作(有点像前后端什么都做),大概07年开始专注在Web前端研发,直到现在。参与过Qzone几大代次的产品结构更新和重构,在海量站点前端性能优化这里有一点小积累。

   

2. 您感觉您关注的领域在过去一年之间有什么明显的变化吗?

徐晓:这个变化就很大了,大家都清楚,因为整个移动互联网杀过来了,用户在终端上花的时间比例不同了。以前专注做Web前端开发的人(某种意义可以称为“浏览器终端”开发),那现在终端从桌面浏览器向手机端的APP来迁移了,研发人员在这块受到的终端迁移影响很大,桌面PC浏览器产品的一些流量,进入一个平台期,增长开始放缓,手机APP用户的活跃会有爆发式的增长,那么这块对我们的技术能力要求就不太一样,有很多需要重新学习的点,这个变化是很明显的。

   

3. 之前看您的一些分享,其实您之前是做的比较偏后端一些的,后来是属于自告奋勇去做了前端工程师。这个您觉得算是一个跨界,做一个全端的工程师吗?

徐晓:我之前的分享里面除了讲到纯Web前端开发的东西外,覆盖了一些网络接入层优化的内容,基本上也是用户侧加上公网这一段的优化,严格说也是偏前端的,不敢当这个所谓的跨界全端。不过我现在也是在告诫自己和鼓励团队,我们至少要在用户端这里要做到“全端”覆盖,包括桌面PC浏览器中的Web开发(当然这个是最经典的),传统的桌面PC的Windows/Mac/Linux应用程序,包括现在手机终端的浏览器Web开发(或者App内嵌WebView中的Web开发),手机终端上的Native App开发,这些领域都要去学习和熟悉。目前在长时间运营Qzone这个海量的社交网络产品过程中,我们的前端工程师除了做经典的Web前端开发外,还要面向运营去做很多现网运营问题的解决,由于用户样本基数很大,会遇到很多非代码逻辑本身的问题,举例说比如公网连通性导致的可用性问题(我是鼓励我们的前端工程师第一时间去受理和定位这些投诉问题的),我们会思考一些基于网络接入层的方案来优化和提升。前端工程师不光是要做出漂亮的rich client,还需要关注更多运维的工作,从客户端架构这里,一开始设计就要思考如何便于后续的运营,网络资源加载如何组织才更高效,故障发生时如何从用户角度做出最细致的柔性可用,这些前端工程师都应该非常关注。再往后去,后端逻辑层,数据层,还有后端集群内的一些容灾和负载均衡等等,虽然目前有nodejs出来,我们可以用前端工程师熟悉的代码语言来做更后端的逻辑架设,但这里需要的意识和经验是不同的,海量业务各层都需要更加细分去研究和挖掘优化点,真正的全端(指那种从前到后的全端,目前比较流行的full stack一说),在比较大型的产品里,对于这里的研发人员来说,是很好的目标,但是路很长。

   

4. 你觉得Qzone的这一块业务,它的前端和后端应该是有什么样的职能划分?

徐晓:拿经典Web这一块来说,这个我们分的比较细了,研发的段落里面,前端细分成页面构建(很多同仁叫页面重构)和前端开发,这里说的稍微直白一点就是所产出的代码逻辑都需要下载到用户的设备上运行,我们都叫前端了,主要是HTML/CSS/JS/AS;后端开发从Web服务器开始到最终存储都是,直白说就是架设出来的系统都跑在我们的服务器设备上,主要是C/C++,少数的php和nodejs;我知道很多大量使用php的产品开发团队里,都把php当作前端工程师来看,但我个人觉得毕竟是运行在服务器上的逻辑,如前面所说,和给浏览器运行的环境还是有本质区别,关注点差异随着持续运营和研究挖掘,分歧点会越来越大。

   

5. 之前看您介绍Qzone框架的平台和应用分离,这个现在有点像是豆瓣最近他们做DAE,整个把平台和应用分离,那他们是一个更加单独的子产品,他们和Qzone的情况不太一样,能不能介绍一下Qzone现在平台的应用分离做到什么程度了?

徐晓:其实我觉得大家做的事情类似,无外乎社交平台,把平台基础服务的产品和在上面运营的一些社交App的产品来做区分,像OS和Application的关系一样,并行发展,互相补充和服务,共同繁荣。

这个涉及到产品架构规划和技术实现两大块,我只谈技术实现。其实从06年QzoneV3重构的时候,已经在用户前端这里,对于个人主页,日志,相册,说说等业务产品有了分离,后端逻辑本身就是分属不同的架构,前端也是最原始的iframe容器+不同页面区分的方式,应该说本身就是分离的,08/09年的时候又经过一些整理,比如梳理出前端和后端服务性API,App前端容器引擎(其实也还是基于iframe容器的前端页面跳转生命期管理),以及App和平台框架的前端通信引擎。有这些为第一步的基础,将现存业务做了平台和应用区分。后来又发展起来新的OpenID体系,以及为接入应用做hosting的服务等等,这些组成Qzone的应用开放平台,也是很完善的独立产品。您说的豆瓣DAE产品,我还没学习研究过,应该也是一种一站式的应用接入引擎,我推测。

   

6. 他是更关注我子应用的开发,整个库是完全独立的。

徐晓:这样有好处,应用可以做到更高效的上线,因为我在应用研发的时候,不需要关注太多基础建设的东西,比如实体机器设备相关的、软件部署相关的等等很多,开发者只需关注本身个性化的一些业务逻辑。这样更高效产生出更多面对细分场景有价值的应用,对平台也是很好的促进。

   

7. 那么你们现在代码提交、集成和开发测试的流程是什么样的?

徐晓:我们这个相对来说比较简单,就还是工程师开发好业务逻辑,进行一定的自测和联调后,提交到svn(近年也在打算往github的方式转,但不是很急)主干,然后提测试申请。测试也比较经典的方式了,就是由测试工程师来过现有的用例。但是我们测试的逻辑很轻,我们现在Qzone这块,每天都会有五到六个发布,那可能是不同的小团队并行来做的,但这是最通常的,可能有时候每天会超过十个发布,很多前端小迭代的发布现在我们是不去测试的,就是开发工程师自己自测,前端逻辑我们更多的是自己去用,只有开发工程师自己去用自己的方法来保证质量。当然人工总是会出错,所以还是要有一些面向现网运营的方案来做质量。我觉得在海量前端这一块,比较重要的还是运营监控,比发布前的一些质量管理更重要。发布前质量管理的一些工作你要更往前移,比如说简单的一些代码疑点扫描,分支运行覆盖度这些东西。代码扫描,你可以放在SVN提交前;那简单的覆盖度扫描我可以集成在我自己的自测工具里面,就比如说我去用自测工具跑一下我的代码,那个工具可以看到我在代码里跑够了多少分支,可能工程师不会自己去做,然后这些可能做到了没有太大的问题,包括浏览器兼容这种都是很原始的,现在都不用太担心。

重点是发布以后,其实更多的我们去看监控了,因为海量业务的前端他跟一般的前端不同,你的用户量太大了,用户那边各种情况都有,你不可能在你这里头通过几个测试设备,或者几十个测试设备就能覆盖了。比如说我们以前有经验,就是用户装了一些网银的插件,都会去影响我们一些脚本的加载执行,或者很早以前有些安全软件,对脚本里面会有一些广告误杀之类的,都会影响,这些是你在一开始测试时很难去想到的一些问题。

所以更多的在用户侧做一些很简单的抽样性质的一些脚本逻辑执行监控、资源加载成功率监控,关键点时延监控,后台接口数据可用性监控等等。监控的粒度应该是宏观和微观两个方向,宏观的监控,通过一个样本量级的波动,可以迅速发现有地域性、运营商收敛的故障;微观的监控是精确到每一个用户的执行情况,比如他这里的浏览器是否遇到运行时脚本异常等,要能够通过异常时的log,完全定位到问题,而不需要再寻找复现场景。这些运营期的保证,才是质量控制的重点,如果我们可以做到快速的发现问题和解决,那么就已经ok了。

   

8. 压力测试这块也是主要靠用户来做?

徐晓:因为压力测试一般只针对服务器,那我们其实前端大家都知道普遍是静态资源,它需要下载到用户的设备上才能开始执行,所以这里的压力其实我们只要保证这个下载没有瓶颈就好,这个下载的压力其实我们通过CDN的分布都可以解决,其实每一个CDN中,最后到末端节点,他们所承载的用户并不多,其实这个问题不大,可能Web接入这一层的压力,其实现在都不是很大的问题。

非静态资源方面,运营了一段时间的服务,你的业务的Web接入这一层都会很有效的分布,你的分布点一般都遍布全国,每个分布点,其实他承载的用户,都不是全量的压力,甚至我很多分布点都有百分之两百,或者百分之三百的冗余。在一些骨干网灾难的时候,可以大面积的,比如说把华南的用户切到华东,那整个华东的这个接入都可以承受。其实你的经验足够的话,在这里不需要真的压力测试,通过一些用户量的情况,都是可以估算来保证的。就是接入再往后的数据层,逻辑层,其实有经验者都可以估测得到。

很多时候可能是新上的服务,你对用户的访问模型不太了解,但是通过灰度放量的方案,先灰度一点点选定的用户,对这一点用户大概产生什么的压力你弄清楚了,其实你全量用户大概也都能推测清楚。这都是一些面向运营的思路,灰度渐进的去放量业务,比再充分的、传统的内部压力测试更重要。当然我们也不是完全不进行压力测试,我了解一些后端系统和基础组件在评估期还是会去严格做的,这种不是所谓的由用户去做。

   

9. 对Qzone App这块,又是怎么样管理方式?比如说我有一个新的APP上线,它可能造成页面延时比较大,这种情况是怎么处理的?

徐晓:这个还是我刚才说的,就说就是从终端,从用户侧的监控去来保证这个事情。比如说我们有一些手段可以去监控用户侧页面上脚本的延迟度,这个如果你上线了一个吃客户端计算资源比较大的Flash,或者JS,我们其实通过这个可以去监控到。然后还有一些就是你页面加载的成功率,比如说我第三方的App上线,那从主页上用户点击这个应用的入口,到应用页面的打开,需要多少延迟?为了帮助App和外部框架来通信,App的页面通常会嵌入我们开放平台的一个JS库,这里可以做一些App自己对平台上报“心跳”的方案,比如告知平台,我现在已经第一视图加载完成。那如果一个用户点击入口,到他页面加载完成,延时很大,这些都是可以实时去发现的,如果发现这些问题,我们当然是从平台侧先给用户,在前端出一些友好的提示,让用户的感受稍微好一点。如果真的是很大的错误,有些公告告知用户大概什么问题。同时我们开放平台的技术支持可能会第一时间通知该App的开发者该问题。

   

10. 在Qzone前端团队,是否有类似雅虎14条军规这样的最佳实践?

徐晓:是有的,当然我们不像雅虎14条这种整理的非常具体,基本上雅虎14条都到了具体实现,对任何程度的开发者来说,都是比较好参考和遵守的。 但其实我们通过实践,也觉得雅虎的这个14条里面有几条,应用的时候,会发现它有一点矛盾在里面。所以,我们不应该是全面机械的去执行,而是把它里面更深的原则参透,所以我们自己的最佳实践更像是一些抽象原则。

我们重点主要还是一些优化思路方面。首先前端逻辑低粒度化,你的业务逻辑应该要非常的低粒度,可以小到一个简单的DOM操作、一个纯展现模板定义,因为绝大部分普通前端业务逻辑开发的情况下,还是比较倾向过程式、函数式的编程风格,比如加载绘制逻辑、事件响应逻辑等,低粒度更适合后续被过程调度组合使用,而且为了更好的被调度组合使用,前端模块化方案和引擎也很繁荣的发展了,RequireJS, SeaJS等等都帮助我们更好的组织更低粒度的前端模块群,更快速的搭建业务逻辑。

有了低粒度模块化,我们就可以谈精确的按需加载,这个比较直白,也是谈的比较多的点,我们从大概06年就开始就有实践,比如一个评论回复框或者验证码逻辑模块,要在用户首次点击TextBox的时候再下载。当然按需下载这个东西,就会带来一些小纠结,真正用到的时候才拉,就感觉第一次会来的有些慢,所以这里就有新的实践点,预加载。什么东西需要预加载?低粒度之后,按需加载之后,有些模块为了让用户用得时候更快,就需要提前预加载。什么时候预加载?你可以根据用户的行为,在下一个逻辑之前的一些必然的先导路径上面,给后面的模块做一个预加载。当然预加载的内容可以很多种,图片、样式、脚本等各种实体文件可以预加载,DNS结果也可以,TCP连接也可以,我们需要打开思路。

还有就是快速响应,就是说你对用户任何一个操作都要有第一时间的瞬时响应。直白来说,就是任何一个操作,都要有一个瞬间的展现上的变化,让用户感知,这是最基本的。稍微进一步的,牵涉到前后端互操作的,就要假定成功先给展现,因为任何一个在线服务的成功率,一般情况下,都应该是至少是95%以上的(打比方,长年低于这个就太可怕了),量大一些的业务,其实都应该是两个九到三个九之间的成功率。那其实很多用户的操作,我们更应该是第一时间就告诉用户成功了,并且不等后端响应直接在前端走成功的逻辑分支并展示。即使真的没成功(算大点1~5%的可能),我们在失败真的发生时,再给用户提示,这样绝大部分用户都会觉得你的服务很快,极少数用户也会在相应的提示下,发现失败,并选择自己需要的操作。这些是比较简单的原则,但其实很多产品在逻辑实现上目前都还没有考虑。再扩展一下到更大范围的场景,不限于有前后端通信的点,也可以是任何一个成功失败分支比例悬殊的逻辑点,这都属于假设成功,快速响应一类。比如说之前听到YouTube的一个例子,那也是很早以前了,就是YouTube大部分视频播放都强依赖Flash Player,他在播放页展现Flash Player之前先要判断用户是否安装Flash Player,或者版本是否满足是8,还是9,还是10、11之类的,先判断完才去展现Flash视频的画幅,判断Flash Player版本的逻辑有比较大的开销(尤其是老IE ActiveX的场景),或导致视频晚出现接近300ms左右。其实大家都知道,基本上95%以上的用户都有Flash Player。其实应该是先把那个Flash Player的HTML先给出来,让大部分人都是第一时间看到,页面最后才去做判断。YouTube这样做了以后视屏平均展现时间提升很多,连成功率都提高了(一部分情况版本判断直接挂掉),这是很不错的又一个假设成功来优化逻辑的案例。

还有就是cache前置化,尽量的把cache往前端来做,能做JS的内存空间的变量的cache或者local storage,就做;做不了,再去考虑HTTP cache control;做不了,你再去考虑服务端,比如说接入层的一些本地session storage之类的,再往后,再去考虑什么memcache之类的这种……就是说一定要很多cache从前端来考虑,因为你从用户侧直接来做,跟随基本上固定的一个用户的使用生命期来cache,贴近用户行为,命中率很可能更好。特别是一个社交平台上,所有内容App都要使用的用户基础profile,前端缓存的效果会很理想,而且这里相对更后端的方案,有更好的成本优势。另外HTML5的发展上,也是在前端存储方案这里有比较大力的拓展,不管是数据内容类还是App资源类,近几年都有很多发展,也是映证这个方向。

上面讲到的几个点低粒度化、按需加载、预加载、快速响应、cache前置等几个点,是我粗略想到的几个比较抽象的点,可能每个展开都可以用更多的场景来映证,推定到不同的具体实施方案。重点还是从用户使用的角度出发,完全面向运营去思考。

InfoQ:挺好的。感谢徐晓的分享!

登陆InfoQ,与你最关心的话题互动。


找回密码....

Follow

关注你最喜爱的话题和作者

快速浏览网站内你所感兴趣话题的精选内容。

Like

内容自由定制

选择想要阅读的主题和喜爱的作者定制自己的新闻源。

Notifications

获取更新

设置通知机制以获取内容更新对您而言是否重要

BT