先后端分离 - 为何用Node.js搭建中间层

什么是中间层

在翻看不少技术文章时,你们都提到“中间层”,在不少大型企业中,Node确实承担了“中间层”的角色,那么,Node为何被普遍的应用在“中间层”呢? html

要回答这个问题,先来陈述下什么是中间层。前端

一般咱们把Web领域分为客户端和服务端,也就是前端和后端,这里的后端就包含了网关,静态资源,接口,缓存,数据库等。而中间层呢,就是在后端这里再抽离一层出来,在业务上处理和客户端衔接更紧密的部分,好比页面渲染(SSR),数据聚合,接口转发等等。web

以SSR来讲,在服务端将页面渲染好,能够加快用户的首屏加载速度,避免请求时白屏,还有利于网站作SEO,他的好处是比较好理解的。那么对于数据的聚合,接口转发来讲,这样作有什么意义呢?数据库

用Node的4点意义

业务驱动

Node有个突出的优点,他的开发者能够是前端。 express

前端对于页面所须要的数据有更好的理解,每一个页面要用到哪些接口,每一个接口要用到哪些字段前端是最清楚的。再加上实际业务开发中,前端页面需求常常会发生变化,须要修改字段或者数据结构,因此对接页面的这部分接口由前端直接开发很是合适,能够显著的减小沟通成本。后端

架构须要

面向用户的接口由Node中间层负责之后,真正的服务端能够专一于提供基于领域模型的对内接口,作微服务。api

好比能够基于Goods模型,提供全部商品相关的接口;基于Users模型,提供全部用户相关接口。当一个接口须要商品+用户信息时,由Node分别查询组装。从总体业务代码维护角度来讲,变得更容易,不会由于业务发展使得每一个接口都异常繁杂。浏览器

性能知足

若是仅仅是架构层面的需求,须要有一个中间层来沉淀业务,那用Java,PHP也能够作到,为何说Node更适合作呢? 缓存

由于Node天生异步!性能优化

众所周知,js是一门单线程语言,因此Node在实现的时候,须要借助libuv来实现异步。

如图所示,libuv为Node提供了线程池,事件池,异步I/O等能力。正是由于其中网络I/O的异步能力,可让Node作接口聚合时,可以更高效的异步并发处理。

成本较低

Node使用js开发,只须要学习简单的api,前端开发者就能够无障碍使用,学习成本很低。

并且,Node具备活跃的社区和丰富的模块池,拥有不少现成的功能实现。框架方面,也有成熟的koa,express等基本框架和egg等二次封装框架,可根据需求选择上手也比较方便。

 

案例:淘宝先后端分离实践

为何要先后端分离

  • 关注点分离
  • 职责分离
  • 对的人作对的事
  • 更好的共建模式
  • 快速的反应变化

阶段一:后端MVC

VIEW层的两种维护方式

1.前端写Demo,后端套页面

问题:后端须要写HTML,且前端仍然须要确认后端写的HTML。

2.前端写View层,后端只管数据

问题:前端须要熟悉后端语言,且前端须要了解后端架构

问题1:前端代码愈来愈复杂

  • 没法统一协做模式,代码充满了约定
  • JS跟CSS,依赖于后段产出的HTML
  • 有的数据來自AJAX,有的数据印在DOM上
  • 有的业务逻辑在前端,有的在Model层,更多的是在View层

问题2:先后端依旧高度耦合

  • 前端依赖服务端开发环境
  • 在服务端View层高度耦合
  • 沟通成本高
  • 职责不清晰

问题3:没法良好的支持跨终端

  • 业务逻辑散落在应用中
  • 渲染逻辑强依赖后端页面
  • 只能用responsive design硬来

问题4:高度耦合的先后端分工

  • 沟通成本上升
  • 维护成本上升
  • 没法正确且快速的响应变化
  • 代码的腐烂只是早晚的问题

阶段二:CLIENT-SIDE MV*

 

接口分离, 后端提供数据, 前端本身搞

  • MODEL层 - JAVASCRIPT OBJECT
  • VIEW层 - JAVASCRIPT TEMPLATE

业界满坑满谷的优秀方案:Backbone, EmberJS, KnockoutJS, AngularJS, React, etc.

先后端职责清晰了

后端 前端
  • 提供数据
  • 处理业务逻辑
  • Server-side MVC架构
  • 代码跑在服务器上
  • 接收数据,返回数据
  • 处理渲染逻辑
  • Client-side MV* 架构
  • 代码跑在浏览器上

 问题1:各层职责重叠,而且各玩各的

  • Client-side Model是Server-side Model 的加工
  • Client-side View跟Server-side是不一样层次的东西
  • Client-side的Controller跟Sever-side的Controller各搞各的
  • Client-side的Route在Server-side可能没有

问题2:性能问题

  • 渲染,取值都在客户端进行,有性能的问题
  • 须要等待资源到齐才能进行,会有短暂白屏与闪动
  • 在移动设备低速网路的体验奇差无比

问题3:重用问题

  • 模版没法重用,形成维护上的麻烦与不一致
  • 逻辑没法重用,前端的校验后端仍须在作一次
  • 路由没法重用,前端的路由在后端未必存在

问题4:跨终端问题

  • 业务太靠前,致使不一样端重复实现
  • 逻辑太靠前,形成维护上的不易

问题5:SEO问题

  • 渲染都在客户端,模版没法重用,SEO实现麻烦

阶段三:从新定义先后端

是依照工做职责来划分的先后端,仍是依照硬体环境划分的先后端?

传统认知的先后端(按硬体环境划分)

从新定义的先后端(按工做指责划分)

在服务器(JAVA)与浏览器(JS)的中间架了一个中间层(NODEJS)

WHY NODEJS

  • 前端熟悉的语言,学习成本低
  • 都是JS,能够先后端复用
  • 体质适合:事件驱动非阻塞I/O
  • 适合IO密集型业务
  • 执行速度也不差

指责划分

后端

前端

服务器 浏览器
JAVA NodeJS JS + HTML + CSS
  • 服务层
  • 提供数据接口
  • 维持数据稳定
  • 封装业务逻辑
  • 跑在服务上的JS
  • 转发数据,串接服务
  • 路由设计,控制逻辑
  • 渲染页面,体验优化
  • 更多的可能
  • 跑在浏览器上的JS
  • CSS、JS加载与运行
  • DOM操做
  • 任何的前端框架与工具
  • 共用模版、路由

职责清晰的架构 + 前端范围的扩展 = 更多的可能

 

实际示例1:淘宝首页优化 

需求

  • 静态资料展现,方便运营管理
  • 更好的承载密集且庞大的流量

解决方案

  • 页面缓存与定时刷新,返回缓存资料
  • NodeJS产出静态页面到CDN,定时刷新

实际示例2:淘宝详情页优化 

需求

  • 单日四亿PV,页面数据来自各个不一样接口
  • 为了避免影响体验,先产生页面框架后再发起多个异步请求取数据更新页面。这些多出来的请求带来的影响不小,尤为在无线端

解决方案

在NodeJS端使用Bigpiper技术,合并请求,下降负担,分批输出,不影响体验。

其余优化:

页面渲染优化

  • 先后端共享模版
  • 首屏服务器渲染
  • 次屏浏览器渲染
  • 局部刷新浏览器渲染

单页面应用优化

  • 先后端共享路由与模版
  • 前端换页,浏览器端渲染
  • 直接输入网址,服务器渲染
  • SEO问题迎刃而解

可靠性优化
单元测试,页面测试,回归测试,持续集成。

接口性能优化
拆分大接口为独立小接口,并发请求。串行 => 并行,大幅缩短请求时间。

部署优化
一台NodeJS对多台JAVA服务器,合理的分配服务器带来最大的产出。

 

优化时秉承的思想:接口服务化   代码模块化   功能组件化

 

转自:

https://2014.jsconfchina.com/slides/herman-taobaoweb/index.html#/

https://mp.weixin.qq.com/s/KzumZwo3ITX0TZvTIhq4vg

相关文章
相关标签/搜索