前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >微信手Q node.js直出框架Hawaii剖析——京东前台技术委员会专题

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

作者头像
京东技术
发布2018-04-10 15:45:13
1.1K0
发布2018-04-10 15:45:13
举报
文章被收录于专栏:京东技术京东技术
手机京东技术团队

作者简介 资深前端开发工程师 京东前台技术委员会委员 微信手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有相似点,后续对其优秀特性会做一下参考。

本文参与 腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2018-03-22,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 京东技术 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 一.Hawaii框架设计的背景
  • 二.Hawaii框架剖析
  • 三.与流行框架对比
    • 与react/vue对比
      • 与GraphQL对比
      领券
      问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档