探討可用於實踐的前後端分離方案

網易考拉前端團隊發表於2018-01-26

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 / 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 非阻塞的方式來呼叫來組裝即可。
更多精彩內容,請關注網易考拉前端團隊微信公眾號

image

相關文章