微信手Q node.js直出框架Hawaii剖析——京东前台技术委员会专题

手机京东技术团队

作者简介 资深前端开发工程师 京东前台技术委员会委员 微信手Q运营产品前端开发组组长 目前负责微信手Q购物入口的前端基础建设及portal开发工作 这篇文章主要讲述了Hawaii框架设计的背景、特有的RDS文件(Request Description Specification)、框架主要特性、与流行框架的对比等。

一.Hawaii框架设计的背景

粗略的讲,web页面的渲染方式可以分为两种:客户端渲染(Client Side Render,CSR,也叫做异步渲染)和服务端渲染(Server Side Render,SSR,也叫做直出)。客户端渲染模式自从ajax技术流行及前后端分离思想提出后,是一种非常流行的模式,确实提升了整体的开发协作效率。但是这种模式也有其弊端,由于客户端需要多次和服务端进行交互,性能和体验比较差。

下面两张图是两种渲染模式的对比:

从上面两张图可以看出,在客户端渲染模式中,不考虑css、图片等因素,客户端至少需要和服务端交互3次才能看到内容。而直出模式中,客户端只需要和服务端交互一次就可以了。网络往返耗时是影响页面性能的主要因素,雅虎13条中最主要的一条就是减少http请求数,微信手Q侧性能统计显示,直出能提升一倍左右的性能,直出也是这几年一个非常热的话题。

直出虽好,但是怎么做直出又是另外一个问题,传统以 Java、c++、php等作为后端语言的直出方式,有以下几个主要问题: + 模板到底是前端维护还是后端维护 + 前后端代码不能复用 + 开发成本高,协作效率低下。

node.js在2009年横空出世之后,JavaScript这么语言在服务端开发领域也有了一席之地,这个也确实让前端同学兴奋了一阵,基于node.js的直出,特别是前后端同构(前后端公用一份代码,并且在前后端都能渲染)也是一个非常热的话题。但是落到实际工程中,在海量服务场景,我们不得不考虑的一个问题是,前端同学的后端能力问题,前端开发思维和后端开发思维差异还是非常大的,前端同学注重业务逻辑实现、页面交互、视觉体验等,后端同学更多的关注如何保障服务稳定性;前后端的技术栈也是差异很大的,做后端要掌握linux、shell、网络、运维和部署等知识。因此,要让每一个前端同学都能负责一个页面的前后端开发,对开发同学的个人素质要求极高,这本身是一件很困难的事情。

提到前后端同构,不得不提到最近流行的两个框架react和vue,但是这两个框架更多是作为一个view层来出现的,实际上我们的业务场景有时候复杂的不是view层,更多的是model层。

下面是一个示例:

因此,理想的直出开发体验应该满足以下几个条件: + 前后端代码及模版复用 + 无需关心服务端实现和处理 + model层的处理足够简单

微信手Q侧的hawaii框架就是满足上面理想条件的一个直出框架: + 前后端代码及模版复用 => 基于node.js + 无需关系服务端实现和处理 => 框架解决 + model层的处理足够简单 => model层可描述

二.Hawaii框架剖析

Hawaii框架是微信手Q侧研发出的关于node.js直出开发的一整套解决方案,其设计核心是一个叫做RDS(Request Description Specification)的请求描述文件,另包括客户端、管理端、服务端及相关调试工具,着重解决model层的复杂性问题,并实现了前后端同构。整体设计如下:

+ 客户端:是一个基于gulp的自动化流程工具,包含脚手架、 本地server、编译等功能。

+ 管理端:包括页面管理、页面及资源发布、页面及接口的监控key管理等。

+ 服务端:统一的直出服务,支持bigpipe,支持多维度监控和容灾。

另外,还有配套的抓包及调试工具,方便直出页面的开发。 使用Hawaii开发的时候,前端同学除了要编写rds文件外,其他的跟普通的开发完全一致,基本目录结构如下:

整个框架设计的核心是RDS文件,RDS文件是一个可编程的json文件,可以对页面model层用到的各种接口进行描述,可支持任意复杂的并行请求、串行请求(父子请求)、条件请求。rds的主要设计如下:

1.一级字段

2.module字段

3.module下的request字段

前端同学在页面开发完成之后,就可以将页面进行编译,将页面拆解为header、footer、template、rds几个部分 ,然后自动上传到管理端。

管理端可以将页面内容一键发布(每个页面有唯一的key来标识)。

上面的index.shtml是异步版页面,容灾用的,其他直出版用的header、footer、template、rds几个部分会同步至redis中。 当直出服务收到渲染页面请求的时候,就开始解析,流程如下:

服务端的核心是解析rds文件,由于rds被设计为支持任意复杂的嵌套,所以其解析也是一个递归解析的过程,下图是解析某一个module的request字段的过程。

每一个模块的request对象解析在响应全部完成之后,最终得到该模块的数据,为一个json对象。然后该模块就可以渲染html内容了。 页面的渲染整体是完全bigpipe式的,最先吐出header部分的内容(保证前端能快速请求和解析css),其他的模块谁就绪谁渲染。

Hawaii除了直出外,也是一个前后端同构框架,主要体现在两点: + 直出服务和前端引擎的代码复用性。 + rds文件及模版前后端均可以解析。 直出服务是在node.js上解析rds文件,而前端引擎是浏览器侧解析rds文件,两者是同一份代码编译出来的。

为了保证页面的可用性,我们的页面是一式三份,必要的时候进行切换。除了直出版外,还有异步版和容灾版: + 异步版:异步版是在编译的时候自动生成,无需做任何的手工处理。异步版自动包含前端引擎及页面的rds文件,解析的时候会请求服务端接口数据。 + 容灾版:容灾版是内部爬虫爬直出服务生成的静态化页面,定期生成,静态版不包含前端引擎及rds文件。

这两个版本分别用于不同的容灾场景,前者其实就是一个客户端渲染版本,对于个性化接口较多的场景比较合适,后者体验更好,但是由于没有调后端接口,一些情况下要做前端个性化逻辑补偿处理。

对于直出来说,必要的异常处理是必要的,下面是Hawaii直出服务的分级处理策略:

另外,页面也做了多维度监控,包括服务级、页面级、接口级,确保对于任何异常都能快速发现和定位。

目前该框架支持了微信手Q部分栏目场景的开发,以及双11和双12大促主会场,后续会推广到更多的场景。该框架也会不断的迭代和优化,主要包括支持更高效的后端通讯、聚合接口支持、支持react/vue组件化、快速/自动扩容/缩容等。

三.与流行框架对比

与react/vue对比

react/vue虽然也有数据层的解决方案并支持前后端同构,但是他们更多的解决view层的复杂性的问题,而hawaii则侧重于解决model层的接口复杂性问题,侧重点不一样。hawaii是一个更底层的框架,后续也会支持react/view组件化。

与GraphQL对比

Hawaii不仅仅支持页面的直出,也可以提供为数据聚合网关。从json聚合接口的焦点来讲,与GraphQL是完全可以对比的,完全具备GraphQL宣称的“请求数据仅需一次请求”、“数据完全按需”两个特点,除了没有类型系统外。类型系统是GraphQL设计上很赞的特性,但是对于已有大量线上应用的大型复杂业务来说,不得不考虑的一个现实是类型系统的设计及改造成本,这个也是GraphQL叫好不叫座的一个重要原因。Hawaii在无需修改现有任何接口和服务的情况下,提供数据一次请求及数据按需两个特性的支持,仍然不失为一个可行且不错的解决方案。

笔者在设计框架的时候,并不了解GraphQL,后来在框架开发就绪时研究GraphQL的时候,发现Hawaii框架确实和GraphQL有相似点,后续对其优秀特性会做一下参考。

原文发布于微信公众号 - 京东技术(jingdongjishu)

原文发表时间:2018-03-22

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏沈唁志

在ThinkPHP5框架中使用QueryList4做采集

23530
来自专栏web前端教室

[一对一讲什么] 之 测完了接口、搞好了目录,然后做啥?

接 [一对一讲什么] 之 切图之后做啥?要加入项目和测试接口 上回书说,切完了页面,把HTML文件啊,CSS,JS,IMG图片什么都扔到相应的开发环境目录里,把...

22180
来自专栏安恒信息

旧版Java/ActiveX浏览器插件存安全漏洞,将遭IE屏蔽

虽然微软的IE浏览器在安全性上已经越来越好,但是由于其庞大的普及率及版本参差不齐,因此有许多旧版本的插件也会让新的IE浏览器成为受到攻击的目标。为...

33160
来自专栏DeveWork

WordPress自定义栏目运用实例Ⅰ:添加文章来源

WordPress 的自定义栏目是一个非常强大的功能,借助它,你的WordPress 站点不仅仅可以是博客,也可以是购物店,企业站,CMS等等。如果你对Word...

20990
来自专栏IT米粉

打造属于自己的博客app——基于react native和博客园接口

关注react native这个技术很久了,去年就做了一个简单的Demo,最近有时间,重新了解了一下react native的现状,发现已经有很大的进步,现在完...

29950
来自专栏企鹅号快讯

卡奇话爬虫使用方法以及下载地址

前不久我给大家分享了CSDN博主虫师的一篇python爬虫编写教程: life is short,u need python. 当时有朋友留言说,并不是每个人都...

22550
来自专栏IT大咖说

通过QQ浏览器内核看browser性能优化

摘要 QQ浏览器内核架构组负责人,通过QQ浏览器X5内核在加载速度、流畅度方面所做的优化工作,带你了解浏览器内核的工作原理、展示前端优化的指导性原则、以及更佳的...

50950
来自专栏企鹅号快讯

小程序也有“home”键盘了!

微信小程序最近仿佛是消停了一会儿儿,没有深夜袭击,不过还是有不断地小更新,今天就来给大家唠叨两个新变化。 --小程序安卓用户更新 12月22日,微信更新了安卓版...

24950
来自专栏编程微刊

小程序新方法 open-type获取头像昵称

小程序自上线以来,官方一直在调整API,因此也出现了一批被废弃的接口,作为程序员的我们,此时此刻千万不能为这不断的变化而感到头疼,应当与时俱进,不断的更新自己的...

42620
来自专栏知晓程序

Android 惊现小程序「入口」,有图有真相!

13330

扫码关注云+社区

领取腾讯云代金券