探讨可用于实践的前后端分离方案

@ImHype 2017-12-16 12:06:34发表于 kaola-fed/blog 待归档

探讨可用于实践的前后端分离方案

Topic

探讨可用于实践的前后端分离方案

Background?

业务发展过程中,技术团队已不再是原来的一人全包或是每个人啥活都干了,更看重每个人术业有专攻。那么,前后端开发如何减少耦合,各自独立地开展工作,是我们值得深层次的思考的问题。

Problems

  1. 环境:进行本地开发,需要起后端环境,如 Tomcat、PHP,影响开发效率
  2. 流程:前端开发先开发 html,再将 html 改写成指定的模板语法(俗称套模板),影响开发效率
  3. 接口:
    • 接口定义一般使用 word 文档,前端开发时不好理解接口字段,影响开发效率
    • 接口变更需要重新编写文档,并重新发送,影响开发效率
    • 文档散落,影响接口维护
  4. 联调:
    • 联调过程变得很复杂,尤其是没有做热部署的Java工程,改视图还需要重启Tomcat,影响前端联调效率
  5. 效益:
    • 前端开发更关注用户体验,而后端只希望关注数据可靠,为实现如响应式、ssr之类的一些交互,前端需要掌控一定的请求响应能力
    • 如果前后端对接的方式转变成为纯粹的 JSON 交换,对于提升开发效率、更清晰的职责与接口复用都是有好处的

出现影响开发效率的事情,就说明现有的模式存在问题。

显然问题的解题思路需要我们重新思考“前后端”的定义。

此时,前后端分离的概念便应运而生,目的是将前后端开发人员的合作方式调节到大家都尽可能舒适的姿势。

Solutions

一、 依托于工具建立的开发阶段前后端分离

Solution

  1. 开发前:前后端约定 JSON 方式的数据,包括页面的渲染数据和一些 api 的响应,后端负责将其整理后定义到接口文档平台;
  2. 开发中:前端开发使用 Dev Server 进行自己的页面开发,并将之前约定的数据在本地模拟;而后端开发更关注于提供给前端约定的数据;
  3. 联调:Dev Server 将原本来自本地的 JSON 数据改为从后端主机取数据)

Summary

  • 这个方案更像是一个流程上的优化,没有实质上解决前后端分工问题,但是开发效率确实大有提升

Problems

  • 模板部分仍依赖于后端,渲染的仍然是一个黑盒,阻碍前端开发定位问题

二、前端 MV* 时代

Solution

浏览器提供可能性:

  • 局部刷新: ajax
  • 前端路由: hashchange/history

框架及工具支持:

  • 框架:vue/react
  • 前端路由 vue-router/react-router
  • 前端数据存储: vuex/redux

前后端分工调整为:

后端 前端
提供数据 接收数据,返回数据
处理业务逻辑 处理渲染逻辑

Summary

  • 移动端设备的设备的提升,性能已经不是瓶颈;
  • 大部分的页面跑在了 app 里面,或是需要登录,seo 要求逐渐降低;
  • 局部刷新是很有效的用户体验提升方式

Problems

  • 需要等待资源到齐才能进行,会有短暂白屏与闪动

三、nodejs 中间层

大杀器 - node.js 中间层

由 Java / PHP 掌控的服务端,极大地限制了我们的想象力,于是我们决定造反了。前端开发作为用户体验关注方,让其负责与用户交互的 gateway 可谓实至名归 。

Solution 1 - Proxy Server

http-proxy 的方式转发用户请求,node.js 这一层是轻量级的 server,不关心具体的业务逻辑,所有请求都会转发给后端 Tomcat 或是 php

注意:

  1. 带上需要转换的字段,如 ip
  2. 使用 node.js agent 模块,开启 http 的 connection: keep-alive,以建立连接池来维护长连接,减少频繁建立连接的时间损失
Dependencies
  • koa - proxy - middleware

Solution 2 - RPC

通过告知目标服务器方法名和方法传递参数的方式去调用一些 api

后端采用微服务的方式,node.js 作为用户端交互的 gateway,对于不同地需求场景,对后端的一些服务做组合调用,最终提供 wap/web/app 三方面的接口调用。

注意: 适用于微服务的后端架构。

Dependencies
  • rpc 调用的 client,思路如下:
    1. 生成 调用方法名调用参数 等数据
    2. encode
    3. 通过 socket 发送数据,并接收目标服务器响应
    4. decode
  • node.js 端开发框架( web 开发规范) - eggjs / nestjs / https://github.com/kappjs/kapp

Node.js server's common dependencies

  • 日志
    • 日志记录 - pm2 logs /log4js
  • 多进程 与 请求的负载均衡 - pm2
    • 多进程 - 充分利用多核,负载均衡 - 合理分配请求到各个子进程
  • Monitor 与 报警
    • 监控日志记录
    • 监控项采集 - 从日志分析出一些监控数据
  • 健康检查
    • 检查 proxy 服务是否可用,rpc 服务是否可用,以决定本身是否可用,如果不可用,则通知 nginx 停止向本台服务器导流
  • 分布式的配置中心
    • 各个工程的配置统一
    • 修改配置立即更新线上

Summary

  • 前端开发需要关注一些服务器端的知识,机遇与挑战
  • 后端服务可靠及稳定性直接决定 nodejs 服务调用时的开发的效率
  • Mock 方式转为更抽象级别的接口 Mock
  • 掌控用户交互的 gateway,我们的目的是提升用户体验,为后续引入首屏直出的服务端渲染方案提供可能性

The End

渐进式的前后端分离方案(个人经验):

  1. 使用 Mock Server 开发,不侵入现有模式;
  2. 觉得有必要掌控服务端来打开我们的想象力,引入 Node.js Proxy Server 中间层,只负责转发请求。在此期间不断完善 Node.js 的基础设施;
  3. 如果业务量巨大,有微服务的需求,推动后端接口服务化进程,Node.js 采用 RPC 方式调用后端接口;反之业务量不大,让后端暴露出一些 web services 的接口,Node.js 使用 http 非阻塞的方式来调用来组装即可。

Thanks!